完整配置
记录下给 php-fpm 的镜像增加 supervisor 服务使其在后台跑多个 worker,如给 php 的 laravel 项目配置多个异步队列进程,使用 supervisor 进行管理。
FROM php:8.2.7-fpm-alpine3.18
ADD https://github.com/mlocati/docker-php-extension-installer/releases/latest/download/install-php-extensions /usr/local/bin/
RUN apk add -f vim && \
apk add --no-cache supervisor
RUN mkdir -p "/etc/supervisor/logs"
RUN chmod +x /usr/local/bin/install-php-extensions && \
install-php-extensions redis pdo_mysql
COPY --from=composer:latest /usr/bin/composer /usr/local/bin/composer
其中最主要的安装的命令为:
apk add --no-cache supervisor
RUN mkdir -p "/etc/supervisor/logs"
如果你用 docker-compose.yml 配置服务,在启动时配置好 command 即可,否则就要在 dockerfile 里配置 CMD 来设置启动命令。
version: '2'
services:
queue:
build:
context: ./
dockerfile: Dockerfile
volumes:
- ./:/app
- ./supervisord.conf:/etc/supervisord.conf
working_dir: /app/backend
command: /usr/bin/supervisord -n -c /etc/supervisord.conf
supervisord.conf 说明
unix_http_server :因为这个容器是前台启动服务,默认不会创建 sock 文件,需要新增一个 unix_http_server 配置,这个配置不需要加 unix 前缀,使用例子中的文件路径即可
supervisorctl:若后续想 exec -it 到这个容器执行一些进程重启或者停止服务,就需要配置 sock 文件,我们默认配置为 supervisord 默认的路径,不改它。
/etc/supervisord.conf:之所以选这地址,而不是 /etc/supervisor/supervisord.conf 是因为很多时候因为基础镜像和 pypi 版本的问题,它不会加载这个配置(即使你的版本大于 3.3.0 也不会去搜索这个目录),导致你启动指定的配置和 supervisorctl 工具默认获取的路径不一致,无法精准获取到 sock 文件。
numprocs = 10: 更改为你想要的进程数,它会在后台自动启动守护。
command:修改为你想要的 worker 启动命令
[supervisord]
logfile=/etc/supervisor/logs/supervisord.log ; main log file; default $CWD/supervisord.log
logfile_maxbytes=5MB ; max main logfile bytes b4 rotation; default 50MB
logfile_backups=10 ; # of main logfile backups; 0 means none, default 10
loglevel=warn ; log level; default info; others: debug,warn,trace
pidfile=/tmp/supervisord.pid ; supervisord pidfile; default supervisord.pid
nodaemon=false ; start in foreground if true; default false
minfds=1024 ; min. avail startup file descriptors; default 1024
minprocs=200 ; min. avail process descriptors;default 200
[rpcinterface:supervisor]
supervisor.rpcinterface_factory = supervisor.rpcinterface:make_main_rpcinterface
[supervisorctl]
serverurl=unix:///run/supervisord.sock ; use a unix:// URL for a unix socket
[unix_http_server]
file=/run/supervisord.sock ;It will not be created by default, it must be written before it will be created
[program:laravel-worker]
process_name=%(program_name)s_%(process_num)02d
command=php/app/backend/artisan queue:work --queue=payment,fetch,default
autostart=true
autorestart=true
stopasgroup=true
killasgroup=true
numprocs=10
redirect_stderr=true
stdout_logfile=/app/backend/storage/logs/worker.log
stopwaitsecs=3600
stdout_logfile_maxbytes=5MB
报错
unix:///run/supervisord.sock no such file
/app/backend # supervisorctl
unix:///run/supervisord.sock no such file
supervisor>
解决方法:在配置文件中配置 unix_http_server 段下的 file 路径就行,切记的你配置文件要和启动程序 supervisord
的路径一直。
[unix_http_server]
file=/run/supervisord.sock
make: /bin/sh: Operation not permitted
如果你编译 php 扩展时,遇到权限错误如:
install-php-extensions redis #0 61.09 make: /bin/sh: Operation not permitted
解决方法:升级最新 docker
我在 Docker 版本 19.03.15 中遇到了类似的错误。将 Docker 更新到 20.10.7 后,此错误消失了。
https://github.com/docker-library/php/issues/1177
https://gitlab.alpinelinux.org/alpine/aports/-/issues/12396
Comments