symfony 6 docker环境需严格匹配php 8.1+及intl/xml/zip/pdo_mysql等强制扩展,否则启动即500;app_env=dev时须禁用opcache与时区校准,database_url主机名必须用服务名db而非localhost,web服务器仅挂载public目录。

用 Symfony 创建 Docker 环境需严格匹配框架版本约束与扩展依赖,直接套用旧镜像或忽略 intl/zip/pdo_mysql 等扩展会导致容器启动即 500 错误,且 APP_ENV=dev 下未禁用 OPCache 将使 Twig 模板修改不生效、配置热更新失效。
选对基础镜像并补全强制扩展
Symfony 6+ 要求 PHP 8.1+,官方 php:8.1-apache 镜像默认不含 ext-intl、ext-xml、ext-zip、ext-pdo_mysql,必须显式安装。否则容器内 Class "Symfony\Component\Intl\Intl" not found 或 Call to undefined function mb_strlen() 会立即触发 500。
方法一:使用社区维护的全扩展镜像(推荐)→ 直接在 docker-compose.yml 中指定:【thecodingmachine/php:8.1-v4-apache】,该镜像已预装 intl、xml、zip、pdo、opcache、mbstring 等全部 Symfony 6 强制依赖扩展。
方法二:自定义构建 → 新建 Dockerfile,以 php:8.1-apache 为基础镜像,追加以下命令:
RUN docker-php-ext-install intl opcache xml zip pdo pdo_mysql \&\& a2enmod rewrite
注意:a2enmod rewrite 必须执行,否则 Symfony 路由全部 404;php:8.1-apache 默认禁用 mod_rewrite。
配置开发环境关键参数
APP_ENV=dev 时,OPCache 和时区必须关闭,否则 DateTime 行为异常、Doctrine 时间字段处理出错、Twig 模板不热更新。
第一步:在 php 服务 environment 下添加:
PHP_INI_SCAN_DIR=/usr/local/etc/php/conf.d
第二步:挂载自定义 php.ini 文件(如 ./docker/php/conf.d/dev.ini),内容必须包含:
date.timezone = "UTC"
opcache.enable = 0
opcache.enable_cli = 0
第三步:删除项目根目录下 .env 文件中的 APP_ENV=prod —— 容器内环境变量、.env、docker-compose.yml 三者冲突时以 .env 为准,不删将导致 APP_ENV 实际为 prod,OPCache 不会关闭。
数据库连接必须用服务名而非 localhost
DATABASE_URL 中 host 写 localhost 是常见错误,容器内 localhost 指向自身,不是 db 服务。
正确写法(MySQL):【mysql://user:pass@db:3306/app】
正确写法(PostgreSQL):【postgresql://user:pass@db:5432/app】
db 必须与 docker-compose.yml 中 database 服务的 service name 完全一致;同时确保 db 服务暴露端口(3306 或 5432),且 php 服务通过 depends_on 声明依赖——但注意:depends_on 只控制启动顺序,不保证 DB 已 ready,首次 doctrine:migrations:migrate 可能失败,需配合 wait-for-it.sh 或重试逻辑。
Web 服务器仅挂载 public 目录
Apache/Nginx 容器不能挂载整个项目目录,否则 public 外的敏感文件(如 .env、config/、src/)可能被直接访问。
正确做法:只挂载 ./public:/var/www/html,并设置 DocumentRoot 指向 /var/www/html。
例如 nginx 配置中:root /var/www/html; → 对应 docker-compose.yml 的 volumes 映射必须是 - ./public:/var/www/html,而不是 - .:/var/www/html。











