Go项目在宝塔中自动退出的根本原因是前台阻塞运行与进程管理器配置不匹配:需为supervisord设autorestart=true、startsecs=0及绝对路径;systemd则须配Type=simple、Restart=always、WorkingDirectory和User=www。

Go 项目在宝塔里启动后自动退出,systemd 或 supervisord 都没生效?
根本原因不是守护进程配得不对,而是 Go 程序默认以「前台模式」运行,一脱离终端就收 SIGHUP;宝塔的进程管理器(比如 supervisord)如果没显式设 autorestart=true 和 startsecs=0,它会误判为“启动失败”直接杀掉进程。
-
supervisord默认要求程序在startsecs秒内进入 RUNNING 状态,而 Go 的 HTTP 服务(如http.ListenAndServe)是阻塞式启动,不返回 —— 这会被 supervisor 当成“卡死”,触发重启或放弃 - 用
systemd时漏写Type=simple(不能用forking),或没加Restart=always+RestartSec=3,进程一崩就躺平 - 脚本里直接写
./myapp没带绝对路径,宝塔执行时$PATH和工作目录跟手动执行不一致,报command not found或找不到配置文件
用 supervisord 管理 Go 项目必须改这三处配置
宝塔自带的 supervisord 插件界面看着方便,但底层配置模板容易忽略关键字段。直接编辑 /www/server/supervisor/etc/supervisor.conf 或对应项目 conf 文件:
- 把
command改成完整绝对路径,例如:command=/www/wwwroot/mygoapp/myapp -config /www/wwwroot/mygoapp/config.yaml - 加上
autorestart=true和startsecs=0—— 后者最关键,告诉 supervisord:“别等返回,只要进程起来了就算启动成功” - 补上
environment=PATH="/usr/local/bin:/usr/bin",HOME="/www/wwwroot/mygoapp",避免依赖系统命令(如调用curl或jq)时报错
为什么不用 nohup ./app & 或 screen?
这些方式在宝塔里等于裸奔:进程不属于任何服务管理单元,系统重启、宝塔重启、甚至面板升级都会清空它们;更麻烦的是,日志不会自动轮转,出错时连 stderr 都捕获不到。
-
nohup启动后,父 shell 退出会导致 Go 程序收到SIGHUP,除非加setsid或exec,但宝塔脚本环境不保证有这些命令 -
screen/tmux在无交互终端下常无法 attach,且宝塔定时任务或重启后 session 彻底丢失 - 真正稳定的方案只有两种:用
supervisord(推荐,宝塔原生支持)或systemd(需手动写 service 文件,但更轻量)
systemd 方案要避开两个路径陷阱
如果你倾向用 systemd(比如部署在 CentOS 7+/Ubuntu 16.04+),注意宝塔用户权限和路径解析和你本地测试完全不同:
- service 文件里
WorkingDirectory必须明确指定,不能省略 —— 否则 Go 应用读取相对路径的config.yaml或静态文件会失败 -
User别写成root,宝塔站点默认跑在www用户下,改成User=www并确保该用户对二进制和配置文件有读/执行权限 - 启动前先手动执行一遍
/bin/bash -c 'cd /www/wwwroot/mygoapp && ./myapp -config config.yaml',确认无权限/路径报错,再丢给 systemd
Go 项目本身没后台模式,所谓“常驻”全靠外部进程管理器兜底;最容易被跳过的其实是工作目录和环境变量这两项,配错一个,日志里就只有一行 exit status 1,根本看不出哪错了。










