推荐使用php:8.2-fpm(debian)或php:8.3-cli镜像,避免php:latest和未验证的8.4;必须安装intl、zip、mbstring扩展,alpine需额外apk add icu-dev,debian则docker-php-ext-install直接生效。

直接用官方 PHP 镜像起步就行,但必须补全 intl、zip、mbstring 这三个扩展——缺任何一个,symfony/translation 或 symfony/routing 在容器里都会报错或降级失效。
PHP 基础镜像选哪个版本?
别硬套最新版。Symfony 6.4+ 推荐用 php:8.2-fpm-alpine 或 php:8.3-cli,8.4 尚未被 Symfony 官方完全验证(截至 2026 年 5 月)。Alpine 小而快,但某些扩展编译麻烦;Debian 系镜像(如 php:8.2-fpm)兼容性更稳,适合 CI/CD 流水线。
-
php:8.2-fpm-alpine:适合生产部署,体积小,需手动装apk add libintl才能让intl正常工作 -
php:8.2-fpm(Debian):开发更省心,docker-php-ext-install intl直接生效,不用额外处理系统库 - 避免用
php:latest或php:8.4——前者不可控,后者在symfony/mime和symfony/translation的部分解析逻辑中存在未修复的时区 fallback 行为
Dockerfile 必须安装的扩展和依赖
只跑 composer install 不够。Symfony 组件在容器里启动时会检查扩展是否存在,不是报错就是静默降级(比如用 polyfill 替代 intl,但消息格式化会出错)。
- 核心扩展:
docker-php-ext-install intl zip mbstring - 如果要用 Xdebug(开发阶段),加一行:
pecl install xdebug && docker-php-ext-enable xdebug,并确保XDEBUG_MODE=debug在环境变量里 - Alpine 用户注意:
intl依赖系统级libintl,得先apk add --no-cache icu-dev,否则docker-php-ext-install intl会编译失败 - 别漏掉
git:某些 Symfony Bundle(如symfony/web-profiler-bundle)在 dev 模式下需要它来读取 Git 分支信息
docker-compose.yml 中的 volume 映射陷阱
本地代码挂载进容器时,路径映射错误会导致缓存失效、权限拒绝、甚至 var/cache 写入失败。
- 开发环境推荐:
- .:/app(项目根目录映射到/app),然后在容器内WORKDIR /app,这样bin/console、public/index.php路径都对得上 - 别写成
- ./symfony:/var/www/html——除非你真把整个项目放在子目录里,否则 Symfony 的 autoloader 会找不到src/和config/ - 生产环境禁用挂载源码:用
COPY . .构建镜像,而不是运行时挂载,否则 opcache 和 realpath 缓存会频繁失效 - 日志目录要双向映射:
- ./logs:/app/var/log,否则APP_ENV=prod下的错误日志根本看不到
APP_ENV 和 APP_DEBUG 的容器化影响
这两个变量不仅控制日志级别,还直接影响路由缓存、翻译缓存、模板编译等行为。设错会导致容器里永远用不上缓存,性能暴跌。
-
APP_ENV=prod时,必须保证APP_DEBUG=0,否则 Symfony 会跳过所有缓存生成逻辑,每次请求都重新解析 YAML 路由文件 - 开发环境用
APP_ENV=dev+APP_DEBUG=1,但要在docker-compose.yml里显式声明,不能依赖.env文件——Docker 容器默认不读宿主机的.env - 若使用
php -S内置服务器(比如快速验证),必须加-t public,否则静态资源 404,且路由无法匹配public/index.php入口
最常被忽略的是 intl 扩展在 Alpine 和 Debian 镜像中的安装差异:Alpine 下少装 icu-dev,docker-php-ext-install intl 看似成功,实则生成的扩展是空壳,运行时一调用就 segfault;Debian 下虽简单,但镜像体积翻倍,CI 构建时间多出 40 秒——得根据场景权衡。











