GitHub Actions自托管Runner中应用启动脚本未运行求助
自托管GitHub Actions Runner中后台启动应用失败的问题解决
问题原因
- 会话回收机制:GitHub Actions自托管Runner的每个Job运行在独立终端会话中,Job执行完成后,Runner会终止该会话下的所有子进程——包括用
nohup启动的后台进程,这是你看不到进程的核心原因。 - 命令执行逻辑隐患:
pkill -f Example && nohup ...中,如果当前没有Example进程,pkill会返回非零退出码,后续启动命令会被跳过。虽然Workflow显示成功,但可能是Runner配置允许步骤忽略错误,或者恰好每次都有进程被kill。
正确的运行方式
方案一:用systemd托管应用(推荐,适合长期运行)
systemd是Linux系统的服务管理器,能保证应用持续运行、崩溃自动重启,系统重启后也会自动启动。
- 创建systemd服务文件
在树莓派上创建/etc/systemd/system/example.service,内容如下(替换对应参数):
[Unit] Description=Example .NET 应用服务 After=network.target [Service] User=ubuntu # 替换为你的Runner运行用户(比如pi或ubuntu) WorkingDirectory=/opt/example # 固定存放应用的路径,避免Runner工作目录变动 ExecStart=/usr/bin/dotnet /opt/example/Example.dll Restart=always # 应用崩溃时自动重启 RestartSec=5 [Install] WantedBy=multi-user.target
- 修改Workflow步骤
在Build步骤后添加复制程序到固定路径的操作,再替换启动命令:
- name: 复制应用到固定路径 run: | sudo mkdir -p /opt/example sudo cp -r Example/bin/Debug/net6/* /opt/example/ sudo chown -R ubuntu:ubuntu /opt/example # 替换为你的Runner用户 - name: 重启应用服务 run: | sudo systemctl stop example.service || true sudo systemctl daemon-reload sudo systemctl start example.service
- 验证服务状态
执行sudo systemctl status example.service查看服务是否正常运行,用journalctl -u example.service -f查看实时日志。
方案二:用screen/tmux临时运行(仅测试用)
适合临时调试,不推荐长期使用,因为系统重启后不会自动恢复。
- 安装screen
在树莓派上执行:
sudo apt update && sudo apt install screen -y
- 修改Workflow启动命令
- run: | pkill -f Example || true screen -dmS example_session dotnet Example/bin/Debug/net6/Example.dll
之后可以用screen -r example_session进入会话查看应用输出,用Ctrl+A+D脱离会话。
额外注意事项
- 权限问题:确保Runner用户有sudo权限(可以通过
sudo visudo配置免密码sudo,方便Workflow执行)。 - 路径稳定性:Runner的工作目录(
_work/仓库名/仓库名)可能在每次Job后被清理或更新,所以最好将应用复制到固定路径运行。
内容的提问来源于stack exchange,提问作者Uit
相关产品推荐
相关产品推荐

