Docker配置Supervisor与Laravel Horizon故障排查:AWS ECS部署后Horizon未激活
Laravel Horizon在AWS ECS中始终Inactive的问题排查与解决
核心问题分析
- Docker启动命令冲突:Dockerfile同时设置
ENTRYPOINT ["./startup.sh"]和CMD ["/usr/bin/supervisord"],实际执行时会将CMD参数传给ENTRYPOINT,即运行./startup.sh /usr/bin/supervisord,但你的startup.sh未处理该参数,导致supervisord根本未启动,Horizon的supervisor配置完全失效。 - Startup脚本阻塞:
startup.sh中php artisan horizon是前台常驻进程,执行到此处后,后续的queue:restart和php artisan serve永远不会执行;且容器主进程为startup.sh,缺少supervisor的进程守护机制,Horizon意外退出后无法自动重启。 - 缺少Horizon必需扩展:composer安装时忽略了
ext-pcntl,而Horizon依赖该扩展管理进程,直接导致Horizon无法正常运行。
具体修复步骤
1. 修复Dockerfile的启动逻辑
删除ENTRYPOINT,让supervisord作为容器主进程,同时安装pcntl扩展:
FROM php:8.1.4-fpm-alpine3.14 RUN apk update RUN apk add --no-cache git libzip-dev zip unzip php8-exif supervisor openssh RUN mkdir -p /usr/src/php/ext/redis; \ curl -fsSL https://pecl.php.net/get/redis --ipv4 | tar xvz -C "/usr/src/php/ext/redis" --strip 1; \ docker-php-ext-install redis; # 安装Horizon必需的pcntl扩展 RUN apk add --no-cache php8-pcntl RUN docker-php-ext-install pdo pdo_mysql zip exif pcntl \ && curl -sS https://getcomposer.org/installer | php -- \ --install-dir=/usr/local/bin --filename=composer WORKDIR /var/www/html COPY supervisord.conf /etc/supervisor/conf.d/supervisord.conf COPY horizon.conf /etc/supervisor/conf.d/horizon.conf COPY startup.sh /usr/local/bin/startup.sh COPY . . RUN chown -R www-data:www-data /var/www/html RUN composer install RUN chmod +x /usr/local/bin/startup.sh # 让supervisord作为容器主进程 CMD ["/usr/bin/supervisord"]
2. 修改supervisord.conf,整合初始化逻辑
让supervisor先执行初始化脚本,再启动sshd和Horizon:
[supervisord] nodaemon=true [program:init] command=/usr/local/bin/startup.sh user=root autostart=true autorestart=false ; 初始化脚本仅执行一次 stdout_logfile=/var/log/init.log redirect_stderr=true [program:sshd] command=/usr/sbin/sshd -D user=root autostart=true autorestart=true [program:horizon] process_name=%(program_name)s command=php /var/www/html/artisan horizon autostart=true autorestart=true user=www-data ; 优先使用非root用户运行 redirect_stderr=true stdout_logfile=/var/log/horizon.log stopwaitsecs=3600
3. 精简startup.sh,仅保留初始化任务
移除阻塞进程的命令,让supervisor管理Horizon和Web服务:
#!/bin/sh # 生产环境建议谨慎使用db:seed,确保逻辑幂等 php artisan migrate --force php artisan db:seed --force php artisan config:cache php artisan route:cache php artisan queue:restart
4. 验证配置与日志
部署后进入容器执行以下命令排查:
# 查看supervisor所有进程状态 supervisorctl status # 查看Horizon运行日志 cat /var/log/horizon.log # 查看初始化脚本日志 cat /var/log/init.log
5. 确认Redis连接配置
确保.env中Redis和队列驱动配置正确:
REDIS_HOST=你的Redis地址 REDIS_PASSWORD=你的Redis密码(如果有) REDIS_PORT=6379 QUEUE_CONNECTION=redis
额外注意事项
- AWS ECS任务角色需具备访问Redis(如使用ElastiCache)的权限。
- 生产环境建议使用Nginx+php-fpm替代
php artisan serve,可在supervisor中添加Nginx进程配置,或单独部署Nginx容器。
内容的提问来源于stack exchange,提问作者Mena
相关产品推荐
相关产品推荐

