Docker一键搭建Nginx+PHP+MySQL建站环境
为什么用 Docker 搭 Nginx+PHP+MySQL
如果你需要在服务器上快速跑起一个 PHP 网站,Docker 一键搭建 Nginx+PHP+MySQL 建站环境是目前比较省事的方式。
它把三个服务拆进独立容器,通过 docker-compose 统一管理,不用在宿主机反复装扩展、调版本。
本文面向零基础用户,从零开始给出完整命令和配置文件,照着做就能在浏览器看到 PHP 页面连接 MySQL 的结果。
适合场景:新服务器初始化、本地开发环境复刻、临时测试站点。
最终你会得到一个可通过 http://服务器IP:8080 访问的 PHP 环境,并且 PHP 能正常连接 MySQL。
开始前的准备条件
动手前先确认几件事,避免中途卡住。
- 一台 Linux 服务器(Ubuntu 20.04+/Debian 11+/CentOS 7+ 均可),建议 2GB 内存以上。
- 已安装 Docker 和 Docker Compose 插件。检查命令:
docker -v和docker compose version。 - 服务器安全组或防火墙放行 8080 端口(本文用 8080 映射 Nginx,避免和宿主机已有 80 端口冲突)。
- 一个用来存放配置和网站文件的目录,例如
/opt/web。
如果 Docker 未安装,可参考官方文档安装,安装后执行 docker run hello-world 能输出欢迎信息即表示正常。
创建目录结构与配置文件
先建好目录,再写 docker-compose.yml。
下面所有操作在 /opt/web 下完成。
mkdir -p /opt/web/{nginx/conf.d,php,www,mysql/data}
cd /opt/web
创建 docker-compose.yml,内容如下:
services:
nginx:
image: nginx:stable
container_name: web-nginx
ports:
- "8080:80"
volumes:
- ./www:/var/www/html
- ./nginx/conf.d:/etc/nginx/conf.d
depends_on:
- php
restart: always
php:
image: php:8.2-fpm
container_name: web-php
volumes:
- ./www:/var/www/html
restart: always
mysql:
image: mysql:8.0
container_name: web-mysql
environment:
MYSQL_ROOT_PASSWORD: root123456
MYSQL_DATABASE: testdb
volumes:
- ./mysql/data:/var/lib/mysql
restart: always
注意:MYSQL_ROOT_PASSWORD 请改成你自己的强密码,不要直接用于生产。
接着写 Nginx 站点配置 nginx/conf.d/default.conf:
server {
listen 80;
server_name localhost;
root /var/www/html;
index index.php index.html;
location / {
try_files $uri $uri/ /index.php?$query_string;
}
location ~ \.php$ {
fastcgi_pass php:9000;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
include fastcgi_params;
}
}
这里 fastcgi_pass php:9000 中的 php 是 compose 里的服务名,Docker 内部网络会自动解析,不需要写 IP。
启动服务并验证连通性
配置写好后,在 /opt/web 目录执行:
docker compose up -d
查看容器状态:
docker compose ps
三个容器都显示 Up 即表示启动成功。
如果某个容器反复重启,用 docker compose logs 服务名 查看日志,常见原因是端口被占用或 MySQL 数据目录权限问题。
写一个测试文件 www/index.php:
connect_error) {
die('MySQL连接失败: ' . $conn->connect_error);
}
echo 'PHP环境正常,MySQL连接成功';
浏览器访问 http://服务器IP:8080,看到“PHP环境正常,MySQL连接成功”就说明整套环境已经跑通。
如果只显示 PHP 源码,说明 Nginx 没有把请求转给 PHP,重点检查 fastcgi_pass 和 PHP 容器是否在运行。
常见报错与避坑说明
端口 8080 被占用:docker compose up -d 会报 bind: address already in use。
改 docker-compose.yml 里的端口映射,例如改成 8081:80,再重新执行 docker compose up -d。
MySQL 容器启动后马上退出:多半是 ./mysql/data 目录权限或已有旧数据不兼容。
可以先 docker compose down,备份后清空该目录再启动。
官方镜像对数据目录权限有要求,不建议手动改所有权为 root 以外的用户。
PHP 报 “Connection refused”:检查 PHP 代码里连接 MySQL 的主机名是否写成 mysql,不要写 127.0.0.1。
在容器网络里,127.0.0.1 指向 PHP 容器自己,不是 MySQL 容器。
修改配置后不生效:Nginx 配置改动后执行 docker compose restart nginx;
PHP 代码改动一般即时生效,无需重启。
安全提醒:本文示例暴露了 8080 端口且使用 root 连接数据库,仅适合学习和内网测试。
正式上线建议限制访问来源、单独创建低权限数据库用户,并定期备份 mysql/data 目录。
几个实际使用中的疑问
这套环境能直接用来跑 WordPress 吗? 可以。
把 WordPress 程序放进 www 目录,数据库连接信息填 mysql、root、你设置的密码即可。
但建议为 WordPress 单独建库和用户,不要长期用 root。
如何进入容器排查问题? 用 docker exec -it web-php bash 进入 PHP 容器,docker exec -it web-mysql mysql -uroot -p 进入 MySQL 命令行。
退出用 exit。
数据会丢吗? MySQL 数据通过 ./mysql/data 挂载到宿主机,删除容器不会丢数据。
但执行 docker compose down -v 会删除卷,操作前确认清楚。
宿主机已有 Nginx 怎么办? 两种做法:把 compose 里的端口改成其他端口,或者让宿主机 Nginx 反代到 127.0.0.1:8080。
后者更适合已经有域名和证书的场景。
整套 Docker 一键搭建 Nginx+PHP+MySQL 建站环境的核心就是三件事:目录挂载、容器网络服务名互通、端口映射。
把这三处理解清楚,后续加 Redis、改 PHP 版本、配 HTTPS 都只是在这个基础上扩展。