最直接可靠的方式是用 docker-compose exec 进入正在运行的 php 服务容器执行 php 命令,复用现有网络、挂载卷和环境变量,确保能正常访问数据库等依赖;需确认服务名、使用容器内路径,并注意 cli 环境是否可用。

在 docker-compose 环境下执行 PHP 脚本,最直接可靠的方式是用 docker-compose exec 进入正在运行的 PHP 服务容器,再调用 php 命令 —— 不要试图在 docker-compose run 中“覆盖 CMD”来执行一次脚本,除非你明确需要隔离环境且不依赖其他服务(如数据库)。
怎么用 docker-compose exec 执行 PHP 脚本
这是开发中最常用、最安全的做法。它复用已启动的服务容器(比如 php 或 app),共享网络、挂载卷和环境变量,能正常访问数据库、缓存、配置文件等。
- 确认服务名:查看
docker-compose.yml中 PHP 容器对应的服务名(常见为php、app、web或fpm),不是镜像名也不是容器名 - 脚本路径必须是容器内路径:比如你挂载了
./src:/var/www/html,那脚本在宿主机./src/artisan,在容器里就是/var/www/html/artisan - 命令格式固定:
docker-compose exec <service_name> php /path/in/container/script.php</service_name> - 带参数或交互时加
-T(禁用伪 TTY)或-it(启用交互,适合需要 stdin 的脚本)
示例(Laravel 项目):
docker-compose exec php php /var/www/html/artisan migrate --force
如果脚本需要读取标准输入(比如 php -r "echo fgets(STDIN);"),加 -it:
echo "hello" | docker-compose exec -it php php -r "echo trim(fgets(STDIN));"
docker-compose run 什么时候该用、怎么避免踩坑
它会启动一个**新容器**,与 exec 的复用逻辑完全不同。适用于一次性、无状态、不依赖其他服务的脚本(比如生成密钥、校验代码风格),但默认不连接 compose 定义的网络,也**不会自动挂载 volumes** —— 很容易报错“文件不存在”或“连不上数据库”。
- 必须显式加
--rm,否则每次执行都残留一个退出容器 - 要用
--network连上 compose 网络(名字通常为<project_name>_default</project_name>,可用docker network ls查) - 要用
-v手动挂载代码目录和配置,否则容器内根本看不到你的脚本 - PHP 镜像若没预装 Composer,
run里也跑不了composer install—— 因为没挂载composer.lock和vendor/缓存
正确示例(生成 Laravel APP_KEY):
docker-compose run --rm --network myapp_default -v $(pwd)/src:/var/www/html php php /var/www/html/artisan key:generate
为什么 php 命令在容器里可能报 “command not found”
不是 PHP 没装,而是你 exec/run 进去的容器镜像压根没配好 CLI 环境。官方 php:<version>-fpm</version> 镜像只含 FPM SAPI,不含 CLI,php 二进制可能被删掉或不在 $PATH 里。
- 检查镜像类型:运行
docker-compose ps,看 PHP 服务用的是php:8.2-fpm还是php:8.2-cli;后者才保证有php命令 - FPM 镜像补救:在
Dockerfile里加RUN ln -sf /usr/local/bin/php /usr/bin/php或直接改用cli镜像 - 别信“PHP 装了就一定有 CLI”—— Alpine 镜像常删掉非必要二进制,
php-fpm镜像默认不带php可执行文件
执行失败时先查这三件事
90% 的问题出在这三个地方,比翻日志更快定位:
-
docker-compose exec php ls -l /var/www/html/your_script.php—— 文件是否存在?权限是否可读?(尤其挂载卷时宿主机 UID/GID 不匹配) -
docker-compose exec php env | grep -E "(DB_HOST|APP_ENV)"—— 关键环境变量是否注入?.env是否被挂载? -
docker-compose exec php php -v和docker-compose exec php which php—— 确认 PHP 版本和路径,排除 CLI 缺失或版本错乱
复杂点在于:你以为在执行脚本,其实是在调试容器环境的一致性。挂载路径、用户权限、网络连通性、环境变量注入顺序 —— 这些都不是 PHP 层面的问题,但全卡在执行前一步。别跳过 ls 和 env,它们比 php --help 有用十倍。
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











