最稳组合是php:8.3-cli-alpine+多阶段构建+ondemand php-fpm:解耦nginx与php、体积小(

直接用 php:8.3-cli-alpine 镜像 + 多阶段构建 + ondemand 模式 PHP-FPM,是 2026 年生产环境最稳的组合。别再用 php:8.3-apache 或全量 Debian 基础镜像了,体积大、启动慢、攻击面宽。
为什么不用 php:8.3-apache 镜像
它把 Web 服务器和 PHP 运行时耦合在一起,违反进程隔离原则;Nginx 更轻、更安全、配置更灵活,且官方 nginx:alpine 镜像体积不到 15MB;php:8.3-apache 默认启用 display_errors=On 和 AllowOverride All,上线前不覆盖极易暴露敏感信息。
- Apache 在容器中无必要:没有 .htaccess 动态重写需求,所有路由应由 Nginx 统一处理
- PHP-FPM 单独运行后,可独立扩缩、健康检查、日志分离
-
php:8.3-apache底层是 Debian,镜像体积常超 450MB;php:8.3-cli-alpine加扩展后仍可控制在 90MB 内
docker-compose.yml 中必须显式设 network_mode 或自定义网络
默认 bridge 网络下,PHP-FPM 容器无法通过 nginx 服务名访问 Nginx,反过来也不行——因为它们根本不在同一网络命名空间。常见错误是 PHP 报 Connection refused 或 Nginx 返回 502,但 docker logs 里看不到连接尝试记录。
- 推荐方案:在
docker-compose.yml顶层加networks: { appnet: { driver: bridge } },然后每个 service 下写networks: [appnet] - 不推荐
network_mode: "host":绕过 Docker 网络栈,失去端口映射和防火墙控制,本地开发可用,生产禁用 - 绝对不要用
network_mode: "service:nginx"(旧文档常见):PHP-FPM 会共享 Nginx 的网络栈,导致localhost解析混乱,curl http://localhost可能打到自己
OPcache 预加载必须配合 /dev/shm 挂载
只在 php.ini 里设 opcache.preload 不生效——PHP 8.3 要求预加载文件必须位于内存文件系统,否则启动时报 Failed to preload 且静默降级为普通缓存。
- Dockerfile 中必须有:
RUN mkdir -p /dev/shm && mount -t tmpfs -o size=256M tmpfs /dev/shm - docker-compose.yml 的 php-fpm service 下要加:
volumes: ["/dev/shm:/dev/shm:rw"] -
opcache.memory_consumption建议设为 256,低于 128MB 时预加载大量类会触发缓存驱逐,反而降低命中率
多阶段构建时 vendor 目录权限容易出错
builder 阶段用 root 跑 composer install,复制到运行阶段后,若容器以 www-data 用户启动,会因 vendor/ 所属用户不匹配导致 autoload 失败或写入失败(比如 Laravel 的 storage/logs)。
- builder 阶段末尾加:
RUN chown -R www-data:www-data /app/vendor - 运行阶段镜像中,必须设
USER www-data,不能只靠docker run --user www-data覆盖 - 避免在运行阶段执行
composer install:既拖慢启动,又可能因无网络或权限问题导致容器反复重启
最易被忽略的是 php-fpm.conf 中的 clear_env = no —— 默认为 yes,会清空所有环境变量,导致你传进来的 DB_HOST、REDIS_URL 全部失效,但错误日志里不会报任何相关提示。
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











