# Sisk アプリケーションのデプロイ

Source: https://docs.sisk-framework.org/ja/docs/deploying.html

Sisk アプリケーションのデプロイプロセスは、プロジェクトを本番環境に公開することから成ります。プロセス自体は比較的シンプルですが、デプロイ先インフラのセキュリティや安定性に致命的な影響を与える可能性のある詳細に注意する必要があります。

理想的には、すべてのテストを実施し、アプリケーションを本番環境にデプロイできる状態にしたうえで、クラウドへデプロイする準備が整っているべきです。

## Publishing your app

Sisk アプリケーションまたはサービスの公開とは、本番環境向けに最適化されたバイナリを生成することです。この例では、.NET Runtime がインストールされたマシン上で実行できるように、本番用バイナリをコンパイルします。

アプリをビルドするにはマシンに .NET SDK がインストールされている必要があり、アプリを実行するターゲットサーバーには .NET Runtime がインストールされている必要があります。.NET Runtime のインストール方法は、Linux サーバーの場合は[こちら](https://learn.microsoft.com/en-us/dotnet/core/install/linux)、Windows の場合は[こちら](https://learn.microsoft.com/en-us/dotnet/core/install/windows?tabs=net70)、Mac OS の場合は[こちら](https://learn.microsoft.com/en-us/dotnet/core/install/macos)をご参照ください。

プロジェクトがあるフォルダーでターミナルを開き、.NET の publish コマンドを実行します:

```shell
$ dotnet publish -r linux-x64 -c Release
```

これにより `bin/Release/publish/linux-x64` にバイナリが生成されます。

> [!NOTE]
> アプリが [ポータブル構成ファイル](https://docs.sisk-framework.org/ja/docs/extensions/service-providers.md) を使用している場合は、`dotnet publish` によって生成されたすべてのバイナリと一緒に `service-config.json` をホストサーバーにコピーしてください。  
> 環境変数やリッスンポート、ホスト、追加のサーバー構成が事前に設定されたままのファイルを残しておくことができます。

次のステップは、これらのファイルをアプリケーションをホストするサーバーへ転送することです。

その後、バイナリファイルに実行権限を付与します。この例ではプロジェクト名を「my-app」とします:

```shell
$ cd /home/htdocs
$ chmod +x my-app
$ ./my-app
```

アプリケーションを実行したら、エラーメッセージが出力されていないか確認してください。エラーが出なければ、アプリケーションは正常に動作しています。

この時点では、ファイアウォールなどのアクセスルールが設定されていないため、外部ネットワークからアプリケーションにアクセスできない可能性が高いです。次のステップでこれを扱います。

アプリケーションがリッスンしている仮想ホストのアドレスを把握しておく必要があります。これはアプリケーション内で手動で設定され、Sisk サービスのインスタンス化方法に依存します。

**ポータブル構成ファイルを使用していない**場合は、`HttpServer` インスタンスを定義した箇所で確認できます:

```cs
HttpServer server = HttpServer.Emit(5000, out HttpServerConfiguration config, out var host, out var router);
// sisk は http://localhost:5000/ でリッスンすべきです
```

手動で `ListeningHost` を関連付ける例:

```cs
config.ListeningHosts.Add(new ListeningHost("https://localhost:5000/", router));
```

ポータブル構成ファイルを使用している場合は、`service-config.json` に次のように記述します:

```json
{
  "Server": { },
  "ListeningHost": {
    "Ports": [
      "http://localhost:5000/"
    ]
  }
}
```

これに基づき、リバースプロキシを作成してサービスをリッスンさせ、オープンネットワーク上でトラフィックを利用できるようにします。

## Proxying your application

サービスのプロキシ設定とは、Sisk サービスを外部ネットワークに直接公開しないことを意味します。この手法はサーバーデプロイで非常に一般的です。その理由は次のとおりです:

- アプリケーションに SSL 証明書を関連付けられるようになる  
- サービスへのアクセス前にアクセスルールを作成し、過負荷を防止できる  
- 帯域幅やリクエスト数の制限を管理できる  
- アプリケーション用にロードバランサーを分離できる  
- インフラ障害時のセキュリティリスクを低減できる  

[Nginx](https://learn.microsoft.com/en-us/aspnet/core/host-and-deploy/linux-nginx?view=aspnetcore-7.0&tabs=linux-ubuntu#install-nginx) や [Apache](https://learn.microsoft.com/en-us/aspnet/core/host-and-deploy/linux-apache?view=aspnetcore-7.0) といったリバースプロキシを介してアプリケーションを提供するか、[Cloudflared](https://developers.cloudflare.com/cloudflare-one/connections/connect-networks/install-and-setup/tunnel-guide/) のような http-over-dns トンネルを利用できます。

また、プロキシの転送ヘッダーを正しく解決し、クライアントの IP アドレスやホスト情報を取得できるようにすることを忘れないでください。詳細は [転送リゾルバ](https://docs.sisk-framework.org/ja/docs/advanced/forwarding-resolvers.md) を参照してください。

トンネル作成、ファイアウォール設定、アプリケーションの実行が完了したら、次はアプリケーション用のサービスを作成します。

> [!NOTE]
> 非 Windows 系統で Sisk サービスに直接 SSL 証明書を使用することはできません。これは HttpListener の実装に起因し、OS ごとに実装が異なるためです。IIS で仮想ホストに証明書を関連付ける場合は [こちら](https://learn.microsoft.com/en-us/iis/manage/configuring-security/how-to-set-up-ssl-on-iis) を参照してください。その他のシステムでは、リバースプロキシを使用することが強く推奨されます。

## Creating an service

サービスを作成すると、サーバーインスタンスの再起動や回復不能なクラッシュが発生した後でも、アプリケーションを常に利用可能な状態に保てます。

このシンプルなチュートリアルでは、前述のチュートリアルの内容を活用し、サービスを常に稼働させる方法を示します。

1. サービス設定ファイルが置かれているフォルダーにアクセスします:

    ```sh
    cd /etc/systemd/system
    ```

2. `my-app.service` ファイルを作成し、以下の内容を記述します:
    
    ```ini {title="my-app.service"}
    [Unit]
    Description=<description about your app>

    [Service]
    # サービスを起動するユーザーを設定
    User=<user which will launch the service>

    # ExecStart のパスは WorkingDirectory に対して相対ではありません
    # 実行可能ファイルへのフルパスを設定
    WorkingDirectory=/home/htdocs
    ExecStart=/home/htdocs/my-app

    # クラッシュ時に常にサービスを再起動するように設定
    Restart=always
    RestartSec=3

    [Install]
    WantedBy=multi-user.target
    ```

3. サービスマネージャーモジュールを再起動します:

    ```sh
    $ sudo systemctl daemon-reload
    ```

4. 作成したサービスを名前で起動し、実行状態を確認します:

    ```sh
    $ sudo systemctl start my-app
    $ sudo systemctl status my-app
    ```

5. アプリが「Active: active」と表示されていることを確認したら、システム再起動後も自動的に実行されるようサービスを有効化します:
    
    ```sh
    $ sudo systemctl enable my-app
    ```

これで準備完了です。Sisk アプリケーションを皆に公開できます。
