PHP本地开发应使用php:fpm+nginx:alpine解耦架构,确保三者网络互通、配置可调、代码修改即生效;禁用OPCache、正确挂载卷、显式配置Nginx日志输出。

PHP 本地开发用 Docker Compose 搭多容器环境,不是“配得越全越好”,而是要让 php、nginx、mysql 三者能通、能调、能改代码即生效——其他服务(如 Redis、Elasticsearch)按需加,别一上来就堆。
为什么不能直接用官方 php:apache 镜像?
官方 php:apache 把 PHP 和 Web 服务器绑死了,你没法单独调 nginx 配置、没法加自定义 rewrite 规则、也没法和前端静态服务(比如 Vite 的 dev server)共存。本地开发要的是“解耦”:PHP 处理动态请求,nginx 做反向代理和静态资源分发。
实操建议:
- 用
php:fpm镜像跑 PHP 进程,只负责处理.php请求 - 另起一个
nginx:alpine容器,通过fastcgi_pass指向php-fpm容器(如php:9000) - 在
nginx容器里挂载自定义default.conf,里面明确写好root、index和location ~ \.php$块 - 确保两个容器在同一个自定义网络(如
app-network),否则fastcgi_pass php:9000会解析失败
MySQL 容器启动后连不上?检查这三处
常见错误是 PHP 报 PDOException: SQLSTATE[HY000] [2002] Connection refused,不是密码错,而是网络或初始化没到位。
实操建议:
-
depends_on只控制启动顺序,不等 MySQL 初始化完成;要在 PHP 应用里加连接重试逻辑,或用healthcheck+condition: service_healthy - MySQL 的
MYSQL_HOST环境变量对 PHP 没用——PHP 连接时必须用服务名(如mysql)当 host,因为 Docker 内部 DNS 是靠服务名解析的 - 默认
mysql:8镜像禁用skip-name-resolve,如果 PHP 容器 hostname 是随机长字符串,可能触发 DNS 反查超时;在mysql的command里加上--skip-name-resolve
代码修改不生效?卷挂载和 OPCache 是两个坑
改了 index.php 刷新页面没变,大概率是 OPCache 缓存了字节码,或者卷挂载路径写错了导致根本没映射上新文件。
实操建议:
- 在 PHP 容器的
php.ini里关掉 OPCache:设opcache.enable=0和opcache.enable_cli=0(开发环境不需要加速) - 确认
volumes挂载路径是否双向正确:例如./src:/var/www/html,且src目录真实存在、有读写权限 - 别用
~/project这种波浪号路径——Compose 不展开它,会导致挂载空目录;一律用相对路径(如./src)或绝对路径(如/Users/you/project/src) - 如果用了 WSL2 或 Docker Desktop for Mac,注意宿主机文件系统与 Linux 容器间的时间戳差异可能导致 OPCache 误判文件未更新;此时干脆禁用更省事
最常被忽略的一点:Nginx 日志默认不输出到 stdout,docker-compose logs nginx 看不到访问记录;得在 nginx 配置里把 access_log /dev/stdout 和 error_log /dev/stderr 显式写上,不然排查 404 或 502 全靠猜。
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











