答案是:用docker一键部署yii2.0.55需创建docker-compose.yml、dockerfile、.env及.dockerignore,配置php-fpm+nginx+mysql 5.7三服务,强制host=127.0.0.1走tcp连接,统一mysql_root_password为yii2dev,并确保nginx.conf根路径指向/frontend/web或/backend/web,缺一不可。

用Docker一键部署Yii2.0.55环境,避免本地PHP版本、扩展、MySQL socket路径不一致导致的“SQLSTATE[HY000] [2002] No such file or directory”或“Access denied for user 'root'@'localhost'”报错,跳过手动装扩展、配php.ini、改host=localhost的繁琐步骤,直接拉起含PHP-FPM、Nginx、MySQL 5.7三服务协同运行的生产就绪环境。
准备基础文件结构
在项目根目录新建三个文件:docker-compose.yml、Dockerfile、.env。确保当前目录下已有Yii2.0.55源码(如advanced模板的backend/web、frontend/web等入口已存在)。
这一步不能跳——Docker Compose会按当前目录为上下文读取文件,路径错一位,build就会失败。
创建空文件后,先写.dockerignore防止vendor被重复复制:vendor/、node_modules/、.git/ 这三行必须写进.dockerignore。
配置docker-compose.yml
复制以下内容到 docker-compose.yml:
version: '3.8'
services:
web:
build: .
ports:
- "8080:80"
depends_on:
- db
environment:
- TZ=Asia/Shanghai
db:
image: mysql:5.7
command: --default-authentication-plugin=mysql_native_password
restart: unless-stopped
environment:
- MYSQL_ROOT_PASSWORD=yii2dev
- MYSQL_DATABASE=yii2app
volumes:
- ./mysql-data:/var/lib/mysql
【必须把MYSQL_ROOT_PASSWORD设为yii2dev】——这是后续config/db.php中默认密码,硬编码在Yii2.0.55 advanced模板的common/config/main-local.php里,不一致会导致连接拒绝。
注意:db服务没暴露3306端口给宿主机,只对web容器内部开放;web容器也不映射443,如需HTTPS请额外加nginx conf并挂载证书。
编写Dockerfile
复制以下内容到 Dockerfile:
FROM php:7.4-fpm-alpine
RUN apk add --no-cache \
nginx \
curl \
git \
libpng-dev \
jpeg-dev \
freetype-dev \
oniguruma-dev \
icu-dev \
mysql-client
RUN docker-php-ext-configure gd --with-freetype --with-jpeg \
&& docker-php-ext-install -j$(nproc) gd pdo_mysql mbstring intl exif bcmath zip opcache
RUN curl -sS https://getcomposer.org/installer | php -- --install-dir=/usr/bin --filename=composer
COPY nginx.conf /etc/nginx/nginx.conf
COPY www.conf /usr/local/etc/php-fpm.d/www.conf
WORKDIR /app
COPY . .
RUN chmod +x yii && chown -R www-data:www-data /app
EXPOSE 9000
CMD ["php-fpm"]
关键点:用alpine而非debian系,镜像体积压到120MB以内;gd扩展必须带--with-freetype和--with-jpeg参数,否则Yii2生成验证码时崩溃;www.conf里user和group必须是www-data,否则Nginx反向代理502。
nginx.conf和www.conf需另建两个文件放在同目录——它们不是可选,缺一不可。
配置Nginx与PHP-FPM联动
新建 nginx.conf,内容如下:
events { worker_connections 1024; }
http { include mime.types;
default_type application/octet-stream;
sendfile on;
keepalive_timeout 65;
upstream php-upstream { server 127.0.0.1:9000; }
server { listen 80;
root /app/frontend/web;
index index.php;
location / { try_files $uri $uri/ /index.php?$args; }
location ~ \.php$ { fastcgi_pass php-upstream;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
include fastcgi_params; } } }
如果用advanced模板,root路径要改为 /app/frontend/web 或 /app/backend/web,取决于你访问哪个入口;不要写成 /app/web ——Yii2.0.55 advanced结构里没有这个路径。
新建 www.conf,仅保留以下三行有效配置:
user = www-data
group = www-data
其余所有行全部删掉——原生alpine的www.conf里listen.user默认是nobody,会导致PHP-FPM拒绝响应。
修正Yii2数据库连接配置
打开 common/config/main-local.php(或 config/db.php),找到 'dsn' => 'mysql:host=localhost;dbname=yii2app' 这行,【必须改成 host=127.0.0.1】。
原因:容器内localhost指向Unix socket,但MySQL容器没挂载socket文件;而127.0.0.1经Docker网络解析为db服务IP,走TCP协议,才能连通。
同时确认 'username' => 'root', 'password' => 'yii2dev' 与docker-compose.yml中一致;'charset' => 'utf8mb4' 建议加上,避免emoji乱码。
启动并验证
执行命令:
docker compose up -d
等待约20秒,运行:
docker compose logs -f web
看到 "started php-fpm" 和 "nginx: [emerg] no port specified" 同时出现,说明Nginx配置有误——立刻检查nginx.conf里server块是否漏了listen 80;
若日志无报错,浏览器访问 http://localhost:8080,出现Yii2欢迎页即成功。
执行数据库迁移:
docker compose exec web php yii migrate/up --interactive=0
这步会自动创建user表等基础结构;若报错“Access denied”,说明db容器未就绪,先 docker compose restart db 再重试。











