Yii应用容器启动失败主因是PHP扩展缺失(pdo_mysql、mbstring、xml、json、ctype)或Apache配置错误(DocumentRoot路径、AllowOverride未启用)、数据库host误写localhost、文件权限不匹配;需用php:8.2-apache镜像,安装并启用扩展,正确配置Apache虚拟主机、数据库服务名及runtime目录权限。

Yii应用启动失败:PHP扩展缺失或配置不匹配
容器里跑不起来,大概率是 pdo_mysql、mbstring、xml 这几个没装全。Yii 3.x 还强依赖 json 和 ctype,但 Docker 官方 PHP 镜像默认不带所有扩展。
实操建议:
- 用
php:8.2-apache或php:8.2-cli基础镜像,别用alpine(除非你愿意手动编译扩展,容易卡在pdo_mysql的 libmysqlclient 上) - Dockerfile 里加一行:
RUN docker-php-ext-install pdo pdo_mysql mbstring xml ctype json - 别漏掉
docker-php-ext-enable—— 某些镜像安装后不会自动启用,得显式调用 - 检查
phpinfo()输出,确认Loaded Configuration File指向的是你改过的php.ini,不是镜像自带的只读副本
Web服务无法访问:Apache配置与Yii入口路径不一致
浏览器打开全是 403 或 404,不是代码问题,而是 Apache 没把请求正确转发给 index.php。Yii 默认靠 .htaccess 做 URL 重写,但官方 PHP-Apache 镜像默认禁用 AllowOverride。
实操建议:
- 在 Dockerfile 中覆盖 Apache 配置:用
COPY apache-yii.conf /etc/apache2/sites-available/000-default.conf -
apache-yii.conf里必须包含:DocumentRoot /var/www/html/web(Yii 2.x)或/var/www/html/public(Yii 3.x),别指向项目根目录 - 确保
<directory></directory>块里有AllowOverride All和Require all granted - 别在
web/目录里放空的.htaccess—— 如果 Apache 没加载mod_rewrite,它反而会触发 500 错误,而错误日志默认被 Docker 吞掉
数据库连接超时:Docker 网络下 host 写成 localhost
本地跑得好好的,一进容器就报 SQLSTATE[HY000] [2002] Connection refused,十有八九是 config/db.php 里还写着 'host' => 'localhost'。
实操建议:
- 把数据库服务名(如
db)当 host 用 ——docker-compose.yml里定义的服务名就是容器间 DNS 名 - Yii 配置中写死
'host' => 'db',别用环境变量拼接再 eval,容易引号逃逸出错 - 加个健康检查:
depends_on: { db: { condition: service_healthy } },并在 db 服务里配好healthcheck(比如用mysqladmin ping -h localhost -u root -proot) - 调试时进 PHP 容器执行:
ping db和nc -zv db 3306,比看 Yii 报错快得多
文件权限混乱:vendor 和 runtime 目录写入失败
容器启动后访问首页报 mkdir(): Permission denied,常见于 runtime/、web/assets/ 或 vendor/ 下的缓存目录。宿主机 UID 和容器内 www-data UID 不一致是主因。
实操建议:
- 构建时用
RUN usermod -u 1001 www-data(和宿主机用户 UID 对齐),而不是反过来改宿主机 - 挂载卷时加
:z(SELinux)或:Z(强制 chcon),尤其在 CentOS/RHEL 上 - 避免直接挂载整个项目目录,改用
COPY . /var/www/html构建镜像,只对runtime/和web/assets/单独挂卷 - 运行前初始化权限:
RUN chown -R www-data:www-data /var/www/html/runtime /var/www/html/web/assets
最麻烦的其实是 Yii 3 的 cache 组件默认用文件存储,又默认写到 runtime/cache —— 这个路径一旦权限不对,连 yii serve 都起不来,但错误提示藏在 STDERR 里,不进容器根本看不到。









