Supervisord 能够实现进程的自动重启,但前提是被托管的程序必须以前台模式运行,且不能是守护进程(daemon)。直接使用 nohup ./app & 将应用放入后台执行,Supervisord 根本无法检测到它的状态,从而无法自动管理。

Supervisord 启动失败或找不到配置文件的原因及解决
安装完毕后没有生成默认配置是常见问题——supervisord 不会自动创建 /etc/supervisord.conf,需要手动初始化:
- 执行
echo_supervisord_conf > /etc/supervisord.conf生成基础配置模板 - 确认配置中的
[include]段已被启用,并且所引用的路径真实存在(例如files=/etc/supervisord.d/*.ini) /etc/supervisord.d/目录必须手动创建,否则运行supervisorctl reread时会静默忽略,不报错也不加载- 启动时务必指定配置文件:
supervisord -c /etc/supervisord.conf,否则 supervisord 可能读取当前工作目录下的$CWD/supervisord.conf,或者直接报unix://tmp/supervisor.sock no such file错误
Program 配置中 autorestart=true 不生效的排查方法
表面上开启了自动重启,实际进程崩溃后并未被拉起,通常卡在以下几个环节:
command定义的启动命令必须以前台方式运行:例如nginx需要加上daemon off;,gunicorn需添加--daemon=false,python app.py不能写成python -m daemon app.pystartsecs设置过小(如设为1),程序刚输出完日志就退出,supervisord 会认为“启动失败”,反复重试直到耗尽startretries次数后彻底放弃- 权限问题:
user指定的用户对command的路径、directory工作目录或日志目录缺乏读/执行/写权限,导致supervisorctl status显示STARTING并卡住不动 - 环境变量缺失:使用
environment=PATH="/usr/local/bin:/usr/bin",HOME="/home/app"显式补全,不要依赖 shell 的$PATH继承
日志写入 stdout_logfile 时报 Permission denied 的解决
supervisord 实际以配置中 user 指定的用户身份写入日志,而非 root——这是最容易被忽略的权限陷阱:
- 确保日志文件所在父目录已存在且可写:例如执行
mkdir -p /var/log/myapp && chown app:app /var/log/myapp - 避免将日志写到
/tmp或/root等普通用户无权限的目录 stdout_logfile_maxbytes与stdout_logfile_backups必须配对设置,否则日志轮转失败后会停止写入- 若设置了
redirect_stderr=true,错误信息不会单独写入stderr_logfile,而是全部合并到stdout_logfile中
supervisorctl status 显示 FATAL 或 BACKOFF 的含义与处理
这通常不是配置语法错误,而是 supervisord 已经尝试拉起进程但持续失败:
FATAL:配置语法错误,或者command指定的路径根本不存在(例如bash: /xxx/app: No such file or directory)BACKOFF:启动失败后按指数退避策略重试(1s→3s→9s),说明程序启动了但立即退出。重点检查stdout_logfile的最后几行,定位是否缺失依赖库、端口被占用、配置文件路径错误等问题STOPPED表示进程被手动停止,并非崩溃;RUNNING才是正常运行;STARTING卡住超过startsecs秒,大概率是权限或路径问题- 调试时建议先关闭
autorestart,手动运行supervisorctl start xxx触发一次,并立即tail -f查看日志,比盲目等待自动重启高效得多
归根结底,真正难以调试的从来不是“怎么写配置”,而是确认被托管的程序——它能否在 supervisord 所指定的用户身份下,不依赖交互终端、不后台运行、不依赖 shell 环境变量,干净利落地启动并保持前台运行。
