docker 安装部署 supervisor 小记
最近工作中用到了 workerman,运行环境为 alpine 构建的基础镜像,计划通过安装 supervisor 来进行容器启动后自动运行 workerman 进程并管理
- 安装 supervisor
apk add --no-cache supervisor
该报错是 supervisor 服务器还未开启
- 配置管理进程
supervisor 默认配置文件路径为 /etc/supervisord.conf,为让避免让该配置文件变成大粽子,我们自定义的配置文件最好是独立配置出来,查看 /etc/supervisord.conf 文件后面可以发现配置会加载同级目录下 supervisor.d/*.ini 所有 ini 后缀的配置文件
- 配置自定义文件
初步配置为以下
日志文件我们当然是要配置映射出来了,免得重启丢失日后排查问题需要是无法排查,pid 文件如果不配置的话会默认生成在 supervisord.conf同级下,我们当然不希望它去污染 etc 目录了。gateway-worker 在容器里只能起一个进程,要不会造成端口冲突。[supervisord] logfile=/webser/logs/gatewayworker/supervisord.log pidfile=/var/supervisord.pid [program:gateway_worker] command=/usr/bin/php /webser/www/start.php start -d numprocs=1 autostart=true autorestart=true startsecs=3 stdout_logfile=/webser/logs/gatewayworker/supervisord_out.log stderr_logfile=/webser/logs/gatewayworker/supervisord_err.log
从上图可以看见 supervisor 启动服务端后,发现 gateway_worker 进程状态是 fatal。通过日志排查,报端口占用的问题,说明在多次重启,为什么呢?
网上了解到,supervisor 会将配置中进程以后台的进程运行,配置中就不能再将命令配置在后台运行了。command=/usr/bin/php /webser/www/start.php start -d
将这条命令的「-d」去掉,看结果
从图中看出已经正常启动了,注意这里修改配置后使用 docker-compose 来重启,否则会遇到另外一个问题,下面开讲。
像上面如果修改了配置文件,会出现意外情况
可以看到存在重复的进程,到底怎么回事?
究其原因是 reload 重新加载配置的时候,supervisor 只关掉了配置中的命令主进程,而命令内生成的子进程没有停掉导致成了孤独进程(这里要手动 kill -9 进程号干掉),如果多次重启不断出现孤独进程那还得了。
其实 supervisor 是支持配置干掉子进程的,如果配置
stopasgroup=true
killasgroup=true
看这下不存在孤儿进程了,这下放心了。
- 配置 supervisor 在容器启动后自动开启服务
在此之前为了让容器挂起,在 docker-compose 配置文件一起使用的command: "tail -f"
,现在肯定要成我们的 supervisor 命令了。command: "/usr/bin/supervisord -c /etc/supervisord.conf"
,只可惜结果未能如我所愿,容器总是一启即退出,这到底又是什么情况?后来换了一种方案,加个启动脚本 start.sh, 在容器启动执行这个脚本command: "bash /var/start.sh"
,脚本就是启动 supervisor 服务,但未能如我所愿。
纳闷!我印象中见过使用 supervisor 命令配置来挂起容器的,为什么不行?到底哪里出了问题?
静下心来搜罗一下,才 get 到另一个点,supervisor 服务默认是以后台进程启动的, 我们再使用 docker-compose 的时候需要配置为前台运行才能让它起到挂起容器的作用。
如何操作?将 supervisor 配置的nodaemon=false
修改为nodaemon=true
,使 supervisor 以前台的方式运行来维护容器的挂起状态。 - 最终配置是这样的
[supervisord] logfile=/webser/logs/gatewayworker/supervisord.log pidfile=/var/supervisord.pid nodaemon=true [program:gateway_worker] command=/usr/bin/php /webser/www/start.php start numprocs=1 autostart=true autorestart=true startsecs=3 stopasgroup=true killasgroup=true stdout_logfile=/webser/logs/gatewayworker/supervisord_out.log stderr_logfile=/webser/logs/gatewayworker/supervisord_err.log
本作品采用《CC 协议》,转载必须注明作者和本文链接
大佬,你是直接把supervisor 安装在php的容器里了?
@mshx 是的
@雪花飘 好的,明白了,谢谢
我也是把supervisor装在php容器里,并且用来消费rabbitMQ队列,但是时间长了mq会断开,是因为php-fpm的原因吗?我本地用homestead不会有这个问题。