Docker化Laravel应用部署Supervisor时的异常问题排查
问题分析与解决办法
所有问题的核心根源是权限不匹配和容器启动时目录/文件初始化顺序错误,结合Laravel容器常用的www-data用户与supervisor运行用户的权限冲突导致。
分步解决方案
1. 解决/var/www/storage/logs/worker.log目录不存在的构建报错
构建阶段(docker-compose build)中,Laravel的storage/logs目录可能未被正确创建,或构建/运行阶段用户不一致。
- 在Dockerfile中添加目录创建与权限配置:
# 构建阶段创建storage日志目录并授权 RUN mkdir -p /var/www/storage/logs \ && chown -R www-data:www-data /var/www/storage \ && chmod -R 775 /var/www/storage - 若使用多阶段构建,需确保将
storage目录完整复制到运行阶段,并保留权限。
2. 解决unix:///var/run/supervisord.sock不存在的问题
该问题源于supervisord未正常启动,或sock文件权限限制了访问:
- 在
supervisord.conf中明确配置sock文件的权限与所属用户:[unix_http_server] file=/var/run/supervisord.sock ; sock文件路径 chmod=0770 ; 允许所属组访问 chown=www-data:www-data ; 指定sock文件归属用户组 - 确保supervisord以
www-data用户运行,而非默认root用户。
3. 解决/etc/supervisor/logs/supervisord.log权限拒绝
此问题是因为/etc/supervisor/logs目录未向运行supervisord的用户授权:
- 在Dockerfile中创建目录并设置权限:
RUN mkdir -p /etc/supervisor/logs \ && chown -R www-data:www-data /etc/supervisor/logs \ && chmod -R 775 /etc/supervisor/logs - 同时在
supervisord.conf中指定运行用户与日志路径:[supervisord] logfile=/etc/supervisor/logs/supervisord.log ; 日志文件路径 user=www-data ; 以www-data用户运行
4. 解决Dockerfile添加CMD后构建循环的问题
构建循环是因为supervisord启动失败导致容器反复重启,需确保CMD命令能正确初始化所有依赖:
- 使用
gosu工具(更优雅的用户切换方式)启动supervisord:# 先安装gosu RUN apt-get update && apt-get install -y gosu && rm -rf /var/lib/apt/lists/* # 启动命令,以www-data用户前台运行supervisord CMD ["gosu", "www-data", "supervisord", "-n", "-c", "/etc/supervisor/supervisord.conf"] - 若无法安装
gosu,也可使用su命令替代:CMD ["su", "-", "www-data", "-c", "supervisord -n -c /etc/supervisor/supervisord.conf"]
关键配置示例
Dockerfile核心片段
FROM php:8.2-fpm # 安装依赖(含supervisor、gosu) RUN apt-get update && apt-get install -y supervisor gosu \ && rm -rf /var/lib/apt/lists/* # 创建所有必要目录并统一授权 RUN mkdir -p /var/www/storage/logs \ && mkdir -p /etc/supervisor/logs /etc/supervisor/conf.d \ && chown -R www-data:www-data /var/www/storage /etc/supervisor \ && chmod -R 775 /var/www/storage /etc/supervisor # 复制supervisor配置文件 COPY supervisord.conf /etc/supervisor/supervisord.conf COPY laravel-worker.conf /etc/supervisor/conf.d/ WORKDIR /var/www # 启动命令 CMD ["gosu", "www-data", "supervisord", "-n", "-c", "/etc/supervisor/supervisord.conf"]
supervisord.conf核心片段
[unix_http_server] file=/var/run/supervisord.sock chmod=0770 chown=www-data:www-data [supervisord] logfile=/etc/supervisor/logs/supervisord.log logfile_maxbytes=50MB logfile_backups=10 loglevel=info pidfile=/var/run/supervisord.pid nodaemon=false user=www-data [rpcinterface:supervisor] supervisor.rpcinterface_factory = supervisor.rpcinterface:make_main_rpcinterface [supervisorctl] serverurl=unix:///var/run/supervisord.sock [include] files = /etc/supervisor/conf.d/*.conf
laravel-worker.conf示例
[program:laravel-worker] process_name=%(program_name)s_%(process_num)02d command=php /var/www/artisan queue:work redis --sleep=3 --tries=3 --max-time=3600 autostart=true autorestart=true user=www-data numprocs=8 redirect_stderr=true stdout_logfile=/var/www/storage/logs/worker.log stopwaitsecs=3600
验证步骤
- 执行
docker-compose build --no-cache清除缓存重新构建 - 启动容器:
docker-compose up -d - 进入容器切换到www-data用户:
docker exec -it <容器名> su - www-data - 检查supervisor状态:
supervisorctl status,确认laravel-worker进程正常运行 - 验证日志权限:
ls -l /var/www/storage/logs/worker.log /etc/supervisor/logs/supervisord.log,确保文件归属为www-data用户
内容的提问来源于stack exchange,提问作者MrCujo
相关产品推荐
相关产品推荐

