Skip to content

将 .NET 应用部署为 Linux systemd 服务

目标

将一个位于 /data 目录下的名为 IpSearch.dll 的 .NET 应用,配置成一个可以在后台运行、开机自启、并在崩溃后自动重启的 Linux 系统服务。

前提条件

  1. 一台 Linux 服务器: 拥有 systemd 的现代 Linux 发行版(如 Ubuntu 16.04+, CentOS 7+, Debian 8+ 等)。
  2. .NET Runtime 已安装: 您的服务器上必须安装了运行应用所需的 .NET 版本。
  3. 应用文件已就位: 您已经将发布的 .NET 应用(IpSearch.dll 及其所有依赖项)复制到了服务器的 /data 目录中。
  4. Sudo 权限: 您需要 sudoroot 权限来创建和管理 systemd 服务。

步骤一:环境验证

在创建服务之前,务必确认您的环境已准备就绪。

  1. 确认 .NET Runtime 工作正常 打开终端,运行以下命令:

    bash
    dotnet --version

    如果能看到版本号输出(例如 8.0.5),说明 .NET Runtime 已正确安装。

  2. 找到 dotnet 的绝对路径systemd 服务配置中需要使用 dotnet 可执行文件的绝对路径。运行 which 命令查找它:

    bash
    which dotnet

    通常输出会是 /usr/bin/dotnet/usr/local/bin/dotnet请记下这个路径,稍后会用到。

  3. 确认应用文件路径 确保您的应用 DLL 确实存在于指定目录:

    bash
    ls -l /data/IpSearch.dll

    如果文件存在,该命令会列出文件信息。如果报错“No such file or directory”,请检查您的文件路径是否正确。


步骤二:创建专用用户(安全最佳实践)

为了安全,不应使用 root 用户来运行应用程序。我们来创建一个专用的非特权用户。

  1. 创建新用户 我们创建一个名为 dotnetuser 的用户,-r 参数表示创建系统账户,-s /bin/false 表示该用户不能用于登录 Shell。

    bash
    sudo useradd -r -s /bin/false dotnetuser
  2. 授予目录权限/data 目录的所有权交给新创建的 dotnetuser 用户,以便该用户有权限读取和执行应用文件。

    bash
    sudo chown -R dotnetuser:dotnetuser /data
    sudo chmod -R 755 /data

步骤三:创建 systemd 服务文件

现在,我们来定义 systemd 服务。

  1. 创建服务单元文件 使用文本编辑器(如 nanovim)在 /etc/systemd/system/ 目录下创建一个新的服务文件。我们将它命名为 ipsearch.service

    bash
    sudo nano /etc/systemd/system/ipsearch.service
  2. 编写服务配置 将以下内容复制并粘贴到打开的文件中。

    ini
    [Unit]
    Description=IpSearch .NET Service
    After=network.target
    
    [Service]
    # -------- 配置核心 --------
    # 工作目录,应用将在此目录下运行
    WorkingDirectory=/data
    
    # 启动命令:使用 'which dotnet' 找到的绝对路径 + 您的DLL文件路径
    ExecStart=/usr/bin/dotnet /data/IpSearch.dll
    
    # 运行服务的用户和组
    User=dotnetuser
    Group=dotnetuser
    
    
    # -------- 进程管理 --------
    # 设置服务在异常退出时总是自动重启
    Restart=always
    # 重启前的等待时间(秒)
    RestartSec=10
    # 用于优雅停止应用的信号
    KillSignal=SIGINT
    
    
    # -------- 日志和环境 --------
    # 在系统日志(syslog)中的标识符,方便筛选
    SyslogIdentifier=ipsearch-service
    # 设置环境变量 (例如,设置为生产环境)
    Environment=ASPNETCORE_ENVIRONMENT=Production
    Environment=DOTNET_PRINT_TELEMETRY_MESSAGE=false
    
    [Install]
    WantedBy=multi-user.target

    重要:

    • 请确保 ExecStart 中的 /usr/bin/dotnet 路径与您在步骤一中找到的路径一致。
    • UserGroup 应与您在步骤二中创建的用户名匹配。

    完成后,保存并关闭文件(在 nano 中,按 Ctrl+X,然后按 Y,最后按 Enter)。


步骤四:管理和运行服务

服务文件创建好了,现在我们可以使用 systemctl 命令来控制它了。

  1. 重新加载 systemd 配置 每次创建或修改服务文件后,都必须执行此命令,让 systemd 读取新的配置。

    bash
    sudo systemctl daemon-reload
  2. 启动服务

    bash
    sudo systemctl start ipsearch.service
  3. 检查服务状态 这是最重要的一步,用于确认服务是否成功运行。

    bash
    sudo systemctl status ipsearch.service
    • 绿色 active (running): 恭喜!服务已成功启动并正在运行。
    • 红色 inactive (dead)failed: 服务启动失败。通常下方会显示错误日志,请根据日志排查问题(常见问题见下方“故障排查”部分)。
  4. 设置开机自启 要让服务在服务器重启后自动运行,您需要“启用”它。

    bash
    sudo systemctl enable ipsearch.service

    执行后,您会看到一条消息,提示已创建符号链接。


步骤五:查看应用日志

您的应用(例如使用 ILogger)输出的日志现在由 journald 管理。您可以使用 journalctl 命令查看。

  • 查看服务的所有日志:

    bash
    sudo journalctl -u ipsearch.service
  • 实时跟踪日志 (类似 tail -f):

    bash
    sudo journalctl -u ipsearch.service -f
  • 查看最近一小时的日志:

    bash
    sudo journalctl -u ipsearch.service --since "1 hour ago"

其他常用命令

  • 停止服务:
    bash
    sudo systemctl stop ipsearch.service
  • 重启服务:
    bash
    sudo systemctl restart ipsearch.service
  • 取消开机自启:
    bash
    sudo systemctl disable ipsearch.service

故障排查

如果服务启动失败 (failed状态),可以从以下几个方面入手:

  1. 查看详细日志: 运行 sudo journalctl -u ipsearch.service -e 查看详细的错误信息。
  2. 权限问题: 确认 dotnetuser/data 目录及其中的所有文件拥有读取和执行权限。
  3. 路径错误: 仔细检查 .service 文件中 ExecStartdotnet 路径和 .dll 路径是否完全正确。
  4. 手动运行: 尝试以 dotnetuser 的身份手动运行应用,看是否报错: sudo -u dotnetuser /usr/bin/dotnet /data/IpSearch.dll 这通常能直接暴露应用本身的问题。
  5. SELinux/AppArmor: 在某些强化安全的系统(如 CentOS)上,SELinux 安全策略可能会阻止服务运行。您可能需要配置相应的策略。

至此,您已成功将一个 .NET 应用配置成了一个健壮的 Linux 系统服务。