必须用docker compose将nginx、php-fpm、mysql三服务绑定启动以实现环境隔离与互通;需定义docker-compose.yml强制自定义网络、配置nginx.conf正确转发至php服务名、构建php镜像时安装opcache等关键扩展,并通过user字段与chown统一uid权限确保runtime可写。

要让PHP网站在本地或服务器上快速跑起来,又不污染宿主机环境,必须用Docker Compose把Nginx、PHP-FPM、MySQL三个服务绑在一起启动,且各服务之间能互相识别、通信、共享代码。
定义服务结构与网络隔离
第一步:在项目根目录新建 docker-compose.yml 文件。
第二步:写入基础服务框架,强制启用自定义网络以避免容器间IP漂移:
version: '3.8'
services:
nginx:
image: nginx:1.25-alpine
ports:
- "80:80"
volumes:
- ./src:/var/www/html:ro
- ./docker/nginx.conf:/etc/nginx/conf.d/default.conf:ro
depends_on:
- php
php:
build: .
volumes:
- ./src:/var/www/html:ro
environment:
- TZ=Asia/Shanghai
mysql:
image: mysql:8.0
environment:
- MYSQL_ROOT_PASSWORD=root123
- MYSQL_DATABASE=tp6
volumes:
- mysql-data:/var/lib/mysql
networks:
default:
driver: bridge
volumes:
mysql-data:
【networks块不可省略】 默认网络名是 default,但若未显式声明 driver,Docker 会回退到 legacy bridge 模式,导致 PHP 容器无法通过 service 名(如 mysql)解析数据库地址。
配置Nginx反向代理PHP-FPM
在 ./docker/nginx.conf 中写入以下内容:
server {
listen 80;
root /var/www/html/public;
index index.php;
location / {
try_files $uri $uri/ /index.php?$query_string;
}
location ~ \.php$ {
fastcgi_pass php:9000;
fastcgi_index index.php;
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
}
}
注意:ThinkPHP 或 Laravel 等框架需将 root 指向 /public 目录,否则静态资源 404;fastcgi_pass 后的 php 是 docker-compose.yml 中定义的服务名,不是 localhost。
构建PHP-FPM镜像的关键指令
方法一:使用 Alpine 多阶段构建(推荐用于生产)
FROM php:8.3-fpm-alpine
RUN apk add --no-cache $PHPIZE_DEPS && \
docker-php-ext-install pdo_mysql mbstring opcache exif
COPY --from=composer:latest /usr/bin/composer /usr/bin/composer
WORKDIR /var/www/html
USER www-data
方法二:基于 Debian 的调试友好型构建(开发阶段可用)
FROM php:8.3-fpm
RUN apt-get update && apt-get install -y libpng-dev libonig-dev libxml2-dev && \
docker-php-ext-configure gd --with-jpeg-dir=/usr/include && \
docker-php-ext-install gd pdo_mysql mbstring opcache
COPY ./php.ini /usr/local/etc/php/php.ini
EXPOSE 9000
⚠️ 如果你用的是 ThinkPHP6,【必须安装 opcache 扩展】,否则框架的类自动加载会慢 3 倍以上,且部分缓存机制失效。
挂载与权限避坑指南
第一步:确保 ./src 目录所有者 UID 与容器内 www-data 用户一致。执行:
sudo chown -R 82:82 ./src(Alpine 中 www-data UID/GID 为 82)
第二步:在 docker-compose.yml 的 php 服务下添加 user 字段:
php:
build: .
user: "82:82"
第三步:禁用 volume 挂载时的默认 root 权限继承——不加 user 字段会导致 PHP 脚本无法写日志、生成 runtime 缓存文件,报错 “Permission denied”。
启动并验证服务连通性
① 执行 docker-compose up -d 启动全部服务。
② 检查容器状态:
docker-compose ps —— 确保所有状态为 Up。
③ 进入 PHP 容器测试 MySQL 连通:
docker-compose exec php php -r "new mysqli('mysql', 'root', 'root123', 'tp6'); echo 'OK';"
④ 访问 http://localhost,看到 PHP 欢迎页或 ThinkPHP 首页即表示 Nginx→PHP→MySQL 链路打通。
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











