docker-compose中自动运行Laravel artisan命令的正确实现方法
你之前配置entrypoint后PHP容器直接退出,核心原因是你覆盖了官方php:8-fpm镜像的默认启动逻辑:迁移命令执行完成后没有启动php-fpm主进程,容器没有前台运行的进程就会自动终止。
关于迁移执行方式的说明
本地开发场景下,手动执行迁移可满足基础需求,但如果要实现一键启动项目,自动化执行是更高效的选择。注意生产环境不要配置自动执行迁移,避免误操作导致数据损坏,建议走手动执行或CI/CD校验后执行的流程。
方案1:单PHP容器整合多进程(适合本地简单场景)
将迁移、队列、调度器、PHP-FPM都放在同一个PHP容器内运行,配置简单。
1. 修改PHP对应的Dockerfile
补充系统依赖安装,新增启动脚本配置:
FROM php:8-fpm # 补充netcat用于检测MySQL端口就绪,修正原配置中apt install无包的问题 RUN apt-get update && apt-get install -y netcat-openbsd \ && docker-php-ext-install pdo_mysql COPY --from=composer:latest /usr/bin/composer /usr/local/bin/composer # 复制启动脚本到容器内 COPY docker/php/start.sh /usr/local/bin/start.sh RUN chmod +x /usr/local/bin/start.sh USER 1000 WORKDIR /var/www/swdocker # 设置启动脚本为入口 ENTRYPOINT ["start.sh"]
2. 编写启动脚本docker/php/start.sh
#!/bin/sh # 等待MySQL服务就绪,避免迁移提前执行失败 while ! nc -z mysql 3306; do sleep 2 done # 执行数据库迁移,--force跳过交互确认 php artisan migrate --force # 后台启动队列监听 php artisan queue:work --daemon & # 后台启动调度器(Laravel 8+支持,仅本地开发可用) php artisan schedule:work & # 启动PHP-FPM主进程,保持容器前台运行 php-fpm
配置完成后重新构建镜像启动即可,无需修改原有docker-compose.yml的PHP服务配置。
方案2:拆分独立服务(符合Docker单进程最佳实践,更稳定)
将迁移、队列、调度器拆分为独立服务,职责单一,故障互不影响,更推荐使用。
调整docker-compose.yml,新增3个服务:
services: # 原有nginx、mysql、php服务保持不变,新增以下服务 migration: build: context: . dockerfile: docker/php/Dockerfile container_name: laravel_migration volumes: - ./:/var/www/swdocker depends_on: - mysql networks: - laravel # 执行完迁移自动退出,不需要重启 restart: "no" command: sh -c 'while ! nc -z mysql 3306; do sleep 2; done; php artisan migrate --force' queue: build: context: . dockerfile: docker/php/Dockerfile container_name: laravel_queue volumes: - ./:/var/www/swdocker depends_on: - mysql - migration networks: - laravel command: php artisan queue:work --daemon restart: always scheduler: build: context: . dockerfile: docker/php/Dockerfile container_name: laravel_scheduler volumes: - ./:/var/www/swdocker depends_on: - mysql - migration networks: - laravel command: php artisan schedule:work restart: always
该方案不需要修改PHP服务的原有启动逻辑,执行docker-compose up -d时会自动按顺序执行迁移、启动队列、调度器和Web服务。
注意事项
- 不要使用固定时长的
sleep等待MySQL就绪,使用端口检测的方式兼容性更强,不会出现MySQL启动慢导致命令执行失败的问题 - Laravel的
schedule:work仅适合本地开发使用,生产环境需要配置cron定时执行php artisan schedule:run - 生产环境请删除自动迁移的配置,避免数据风险
内容的提问来源于stack exchange,提问作者Evg127
相关产品推荐
相关产品推荐

