# 部署您的 Sisk 应用程序

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

部署 Sisk 应用程序的过程包括将项目发布到生产环境。虽然该过程相对简单，但值得注意的细节可能对部署基础设施的安全性和稳定性产生致命影响。

理想情况下，在完成所有可能的测试并使应用程序准备就绪后，您应该准备好将其部署到云端。

## 发布您的应用

发布 Sisk 应用程序或服务即生成适用于生产环境的二进制文件并进行优化。在本示例中，我们将编译用于生产的二进制文件，以在已安装 .NET Runtime 的机器上运行。

您需要在机器上安装 .NET SDK 以构建应用程序，并在目标服务器上安装 .NET Runtime 以运行应用程序。您可以了解如何在 Linux 服务器上安装 .NET Runtime [此处](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/zh-cn/docs/extensions/service-providers.md)，应将 `service-config.json` 与 `dotnet publish` 生成的所有二进制文件一起复制到宿主服务器。您可以保留该文件的预配置内容，包括环境变量、监听端口和主机以及其他服务器配置。

下一步是将这些文件传输到将要托管应用程序的服务器上。

之后，为二进制文件授予执行权限。在本例中，假设我们的项目名称为 “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/"
    ]
  }
}
```

基于此，我们可以创建反向代理来监听您的服务，并使流量在开放网络上可用。

## 为您的应用程序设置代理

为服务设置代理意味着不直接将 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) 来提供应用程序，或者使用 http-over-dns 隧道如 [Cloudflared](https://developers.cloudflare.com/cloudflare-one/connections/connect-networks/install-and-setup/tunnel-guide/)。

此外，请记得正确解析代理的转发头，以通过 [转发解析器](https://docs.sisk-framework.org/zh-cn/docs/advanced/forwarding-resolvers.md) 获取客户端信息，如 IP 地址和主机。

在创建隧道、防火墙配置并使应用程序运行后，下一步是为您的应用程序创建一个服务。

> [!NOTE]
> 在非 Windows 系统上，无法在 Sisk 服务中直接使用 SSL 证书。这是 HttpListener 实现的限制，HttpListener 是 Sisk 中处理 HTTP 队列管理的核心模块，而该实现因操作系统而异。如果您在 IIS 上[将证书关联到虚拟主机](https://learn.microsoft.com/en-us/iis/manage/configuring-security/how-to-set-up-ssl-on-iis)，则可以在 Sisk 服务中使用 SSL。对于其他系统，强烈建议使用反向代理。

## 创建服务

创建服务将使您的应用程序始终可用，即使在服务器实例重启或不可恢复的崩溃后也是如此。

在本简易教程中，我们将使用前面教程的内容作为示例，以保持服务始终处于活动状态。

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 应用程序。
