Help us understand the problem. What is going on with this article?

Win上でビルドした.NET Core Webアプリを、CentOS7で実行するまでの最短環境構築 (開発デプロイ編)

More than 1 year has passed since last update.

なにする

CentOS事前準備編(Linux側の準備)の続きで
こちらでは
「開発環境の準備~デプロイ、Linux上で実行するまで」
の部分の流れを超ざっくり追います。

はじめに

(事前準備編でサーバの用意ができている状態から、)
開発環境となるVSCodeを用意してデモプロジェクトを発行、
それをビルドしてLinuxに持っていき起動します。
それをApacheのリバースプロキシでアクセス可能にするまでの開発デプロイ編です。
(前回がインフラチームの作業だとすれば、こちらは開発者が担当する部分かな)

開発デプロイ編 はじめます!

ローカル開発環境を作る

環境はWindows(10)です。

# Portable版(.zip)もあるでよ。私はこれ。

これだけです。

デモプロジェクトを用意してビルド(publish)する

# 予め用意されているテンプレというかデモプロジェクトがありますので、
 それを取得してビルド(publish)して持っていきます。

作業用フォルダを作っておき、VSCodeを立ち上げて開きます。
その状態で、ターミナルで以下のコマンドを打ち、プロジェクトを展開します
(ターミナルはメニューかCtrl+@で開きます)

> dotnet new webapp -o RazorPagesMovie

これでフォルダにファイルができあがります。
ライブラリがないよ、とかのポップアップが出たら「Yes」で勝手に入ります。

とりあえずローカルで動かす

.csprojのある場所に移動して、runすると動きます

> cd RazorPagesMovie
> dotnet run

エラーなどが出なければ http://localhost:5000/ でLISTENしてるよって出るので、アクセス。
正常にデモサイトが見れたらOKです。

なお、ポート番号を変更する場合や、Linux上で動作させる場合にhttpsを使用しない場合
下記ファイル、下記の箇所のapplicationUrlの部分も書き換えます。
(localhostはそのままでも変えても大丈夫。今回は下記で行きます)

\Properties\launchSettings.json
    "RazorPagesMovie": {
      "commandName": "Project",
      "launchBrowser": true,
      "applicationUrl": "http://localhost:5000",
      "environmentVariables": {
        "ASPNETCORE_ENVIRONMENT": "Development"
      }

ポート番号を変える場合
ポート番号を変える場合は、上記のapplicationUrlだけ変えても
CentOS展開時に反映されなかったため、以下も追記します。

\Program.cs
        public static IWebHostBuilder CreateWebHostBuilder(string[] args) =>
            WebHost.CreateDefaultBuilder(args)
                .UseStartup<Startup>()
                .UseUrls("http://localhost:5001") // ここを追記
            ;

ちなみに補足、解説

これをpublishして持っていけば動くんですが…

.NET Webは上記のように、
ポート番号に対して独自のWebサーバ(Kestrel:ケストレル)が起動します。
# なので、1プロジェクトごとにポート番号が要ります。
 (ちなみにこのポート番号はApacheに経由してもらうため、ファイアウォールの設定は不要)

Linux側ではこれをApacheのリバースプロキシで経由して見せるわけですが、
素直に転送するとドキュメントルート直下で動くようなイメージになります。

サブドメインなどを切れる場合などは問題ありませんが、
もしそうでない場合で
例えばディレクトリごとにプロジェクトを起動したい、という場合などは
あらかじめプロジェクト内のパスも、それを想定したパスにしておく
# ドキュメントルート直下にならないので。
といった対応が必要です。

そんな場合のナレッジも兼ねて、
私もそう詳しくないのですが、あらかじめあるディレクトリ以下にする方法を載せておきます。

\Startup.cs
            app.UsePathBase("/path/to/project_directory"); // ※ app.UseStaticFiles();に影響します
            app.UseStaticFiles();

※ app.UseStaticFiles() より前に記載すると、静的ファイル参照時の起点も同じディレクトリからになります。
  app.UseStaticFiles() より後に書けばパスの指定がかからないため、Kestrelのドキュメントルート起点になります。

このように、パスとKestrel側の(プロジェクト側の)ポート番号が異なっていれば
Apacheへのアクセスは80番のみ(1つのポートのみ)でも
それぞれのパスに対応したプロジェクトにアクセスさせることができます。

それではpublishします

外部のサーバに合わせたRID(ランタイム識別子)を指定することで、その環境用にビルドできます。
RIDのカタログはこちら

> dotnet publish --runtime centos.7-x64

※ ちなみにbuildコマンドもありますが
  ASP.NETとかだとbuildすれば他の環境でも動きましたが
  .NET Coreでは自環境で動く最低限しかファイルが用意されないので
  buildしたものを持って行っても動きません。

\bin\Debug\netcoreapp2.1\centos.7-x64\publish にファイルができます。
できたdll達をsambaで持っていくことでサーバへの展開は完了です。
(持っていくときは単純に公開するパスに合わせて配置の想定です)

Linuxで起動

まずは手動で動かしてみる

Windowsでrunした時と同じように、とりあえず起動確認だけしておきます。
Linuxにログインして、先ほど展開したフォルダまで移動し、dotnetコマンドでメインのdllを実行します。

dotnet ./RazorPagesMovie.dll

runしたときと似たようなのが出て、待機状態になります。
この状態では外部からアクセスできないので、
エラーが出なければとりあえずOKです。

サービスとして登録する

都度手動起動して走りっぱなしにしておくわけにもいかないので、
サービスとして登録して起動します。

vi /etc/systemd/system/(ファイル名は適当でOK).service

ファイルの内容はこんな感じで、最低限必要なのはパスの部分の調整です

(さっきの).service
[Unit]
Description=Example .NET Web API App running on CentOS 7

[Service]
WorkingDirectory=/home/apache/vhost/path/to/project_directory
ExecStart=/usr/bin/dotnet /home/apache/vhost/path/to/project_directory/RazorPagesMovie.dll
Restart=always
# Restart service after 10 seconds if the dotnet service crashes:
RestartSec=10
SyslogIdentifier=dotnet-example
User=apache
Environment=ASPNETCORE_ENVIRONMENT=Production

[Install]
WantedBy=multi-user.target

こうして作ったファイルをサービスとして登録します。

### 自動起動有効化
systemctl enable (さっきの).service

### 起動
systemctl start (さっきの).service

### 確認
systemctl status (さっきの).service

Apacheでリバースプロキシを設定する

最後に、外部からのApacheへのアクセスをKestrelに転送するため
リバースプロキシを設定します。

vi /etc/httpd/conf.d/vhost.conf
/etc/httpd/conf.d/vhost.conf
<VirtualHost *:*>
        RequestHeader set "X-Forwarded-Proto" expr=%{REQUEST_SCHEME}e
</VirtualHost>

<VirtualHost *:80>
        ServerName 192.168.0.123
        DocumentRoot /home/apache/vhost
        <Directory "/home/apache/vhost">
                Require all granted
        </Directory>

        ProxyPreserveHost On

        # 以下を環境に合わせて追記。トレイリングスラッシュは無し。
        ProxyPass /path/to/project_directory http://localhost:5000/path/to/project_directory
        ProxyPassReverse /path/to/project_directory http://localhost:5000/path/to/project_directory
</VirtualHost>

重要なのはProxy…の部分で、他のは前回設定した内容とかです。
今回はApacheで受けたパスを5000番ポートにそのまま流す形です。

### 確認して
apachectl configtest
### 反映します
systemctl restart httpd

これでアクセスしてみて見ることができれば、とりあえずは公開完了!になります。

お疲れさまでした!!

Why do not you register as a user and use Qiita more conveniently?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away