在docker容器中执行php cli脚本最常用方式是docker exec,需确保容器运行、内置php cli、权限与路径正确;一次性任务用docker run --rm挂载执行;定时任务推荐supercronic等独立调度容器而非容器内cron。

docker exec 在运行中的容器里执行 PHP 脚本
这是最常用也最直接的方式,适合维护、调试或触发框架命令(比如 artisan migrate)。前提是容器已启动且内部装有 CLI 版 PHP。
- 先确认容器里真有
php命令:docker exec my-app which php—— 如果返回空或php: not found,说明你用的是纯php-fpm镜像(如php:8.2-fpm),它默认不带 CLI;得换用php:8.2-cli或在构建时显式安装 - 执行脚本时注意用户权限:
docker exec -u www-data my-app php /var/www/html/script.php,否则可能因文件属主不匹配报错Permission denied - 工作目录很重要:
-w /var/www/html能避免相对路径失效,尤其当脚本里用了require 'config.php'这类语句时 - 传参写法是
docker exec my-app php script.php arg1 arg2,参数直接跟在脚本路径后,不要加--
docker run 一次性执行本地 PHP 脚本
适合 CI/CD 中跑迁移、数据同步等临时任务,不用长期占用容器资源,也绕过“容器没启”的麻烦。
- 用
-v挂载宿主机脚本进容器:docker run --rm -v $(pwd)/myscript.php:/tmp/script.php php:8.2-cli php /tmp/script.php。注意路径必须是绝对路径,$(pwd)是安全写法 - 如果脚本依赖项目代码或配置,别只挂单个文件——挂整个目录更稳妥:
-v $(pwd):/app -w /app,再执行php index.php - 镜像选
php:8.2-cli而不是php:8.2-fpm,后者没有php命令,会直接失败 -
--rm必须加上,否则每次执行都会残留一个已退出的容器,日积月累填满docker ps -a
PHP 脚本自动执行:cron 还是独立调度容器?
想让脚本定时跑,别在容器里硬塞 cron 服务——主进程冲突、日志难查、升级困难。优先用外部调度。
- 宿主机 crontab 调
docker exec最简单,但耦合强:某天容器名改了或停了,任务就静默失败,还没告警 - 推荐用
supercronic或ofelia这类专用调度容器,通过docker-compose.yml定义,和业务容器网络互通,失败时能发日志甚至通知 - 无论哪种方式,脚本本身要幂等:重复执行不能出错(比如
migrate已存在表就跳过),否则定时器一卡就连锁故障 - 环境变量别靠
docker exec -e传——容易漏或覆盖,统一走docker-compose.yml的environment或.env文件
常见错误:为什么脚本执行了却没效果?
多数问题不在 PHP 语法,而在容器内外的路径、权限、扩展缺失这三块。
-
Class 'PDO' not found:基础镜像没装pdo扩展,Dockerfile 里得加RUN docker-php-ext-install pdo pdo_mysql -
failed to open stream: Permission denied:宿主机文件挂载后属主变成root,而容器用www-data用户跑,得在docker run时加-u www-data,或构建镜像时RUN chown -R www-data:www-data /var/www/html -
Connection refused(连 MySQL):别用127.0.0.1,Docker 网络里服务名才是地址,比如mysql或db,取决于docker-compose.yml里定义的服务名 - 脚本输出看不见?加
-t参数:docker exec -t my-app php script.php,否则部分缓冲行为会导致 stdout 不实时刷出
docker exec -it my-app bash 进去手动跑一遍,再逐步把参数挪到 docker exec 命令里,比直接拼长命令靠谱得多。php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











