本文约 3,731 字,预计阅读 10 分钟。文中命令与配置均经过实测,可直接参考执行。
引言:为什么越来越多站长改用容器部署
传统方式装 WordPress,要装 Nginx、装 PHP-FPM、装 MySQL、配伪静态、改权限,一圈下来两三个小时,换台服务器还得再来一遍。更麻烦的是线上 PHP 是 7.4、本地是 8.2,插件行为不一样,排查问题全靠猜。
用 Docker Compose 部署的好处很直接:环境可复制、版本可锁定、迁移只需拷文件、回滚就是把镜像版本号改回去。对个人开发者和中小团队来说,这是性价比最高的部署方式。
原理分析:Compose 到底解决了什么问题
Docker 只负责”跑一个容器”,而 WordPress 至少需要两个容器:Web(Apache/Nginx + PHP)和数据库。手工用 docker run 也能起,但你要自己建网络、自己配环境变量、自己管启动顺序。
Docker Compose 用一个 YAML 文件声明这几件事:
- 服务(services):定义 wordpress、db 两个容器用什么镜像、什么参数;
- 网络(networks):Compose 会自动建一个内部网络,容器之间用服务名互相访问(所以数据库主机填
db而不是localhost); - 卷(volumes):把容器内会变化的数据(数据库文件、wp-content)映射到宿主机,容器删了数据还在;
- 依赖(depends_on):控制启动顺序。
理解这四件事,剩下的配置就是填空题。
保姆级实操
第一步:安装环境
# Ubuntu / Debian
sudo apt update && sudo apt install -y docker.io docker-compose-plugin
sudo systemctl enable --now docker
docker compose version # 输出版本号即安装成功
第二步:建目录与编排文件
mkdir -p /opt/wp-site && cd /opt/wp-site
vim docker-compose.yml
services:
db:
image: mariadb:10.11
container_name: wp-db
restart: unless-stopped
environment:
MARIADB_ROOT_PASSWORD: "${DB_ROOT_PASSWORD}"
MARIADB_DATABASE: wordpress
MARIADB_USER: wpuser
MARIADB_PASSWORD: "${DB_PASSWORD}"
volumes:
- db_data:/var/lib/mysql
command: --character-set-server=utf8mb4 --collation-server=utf8mb4_unicode_ci
wordpress:
image: wordpress:6.7-php8.2-apache
container_name: wp-web
restart: unless-stopped
depends_on:
- db
environment:
WORDPRESS_DB_HOST: db:3306
WORDPRESS_DB_NAME: wordpress
WORDPRESS_DB_USER: wpuser
WORDPRESS_DB_PASSWORD: "${DB_PASSWORD}"
WORDPRESS_CONFIG_EXTRA: |
define('WP_MEMORY_LIMIT', '256M');
define('FS_METHOD', 'direct');
volumes:
- wp_data:/var/www/html
ports:
- "8080:80"
volumes:
db_data:
wp_data:
密码不要写死在 YAML 里,同目录建 .env:
DB_ROOT_PASSWORD=换成强密码
DB_PASSWORD=换成另一个强密码
第三步:启动与验证
docker compose up -d
docker compose ps # 两个容器状态应为 Up
docker compose logs -f wordpress # 看启动日志
浏览器访问 http://服务器IP:8080,进入熟悉的 WordPress 安装向导。
第四步:接 Nginx 反代并配 HTTPS
生产环境不建议直接暴露 8080,前面放一层 Nginx:
server {
listen 80;
server_name mimangfei.com www.mimangfei.com;
client_max_body_size 64m;
location / {
proxy_pass http://127.0.0.1:8080;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
}
因为走了代理,WordPress 需要处理协议头,否则会出现 CSS 加载、后台反复跳登录的问题。在 wp-config.php 里加:
if (isset($_SERVER['HTTP_X_FORWARDED_PROTO']) && $_SERVER['HTTP_X_FORWARDED_PROTO'] === 'https') {
$_SERVER['HTTPS'] = 'on';
}
内链锚文本:
WordPress 后台反复跳转登录的排查方法
第五步:备份
# 数据库备份
docker compose exec db mysqldump -u wpuser -p"$DB_PASSWORD" wordpress > wp-$(date +%F).sql
# 文件备份
tar czf wp-content-$(date +%F).tar.gz \
$(docker volume inspect wp-site_wp_data -f '{{ .Mountpoint }}')
常见踩坑与失败案例
- 数据库容器一直重启:十有八九是
db_data卷里残留了旧版本 MariaDB 的数据文件。换大版本前先备份,再docker compose down -v清卷重建。 - 后台提示”无法创建目录”:容器内 Apache 运行用户是
www-data,而挂载卷属主是 root。执行docker compose exec wordpress chown -R www-data:www-data /var/www/html/wp-content即可。 - 上传文件被限制为 2MB:限制来自 PHP 而不是 Docker。挂一个自定义配置:
./uploads.ini:/usr/local/etc/php/conf.d/uploads.ini,内容写upload_max_filesize = 64M与post_max_size = 64M。 - 改了 YAML 不生效:
docker compose up -d只重建变化的容器;改了环境变量仍不起效就docker compose up -d --force-recreate。 - 真实踩坑案例:有人把
WORDPRESS_DB_HOST写成localhost,容器内根本没有 MySQL,页面直接”建立数据库连接时出错”。Compose 网络里必须填服务名db。
总结
Docker Compose 部署 WordPress 的核心不在”会不会敲命令”,而在于把数据(卷)、配置(环境变量)、访问(端口/反代)三件事分开管理。只要卷挂对了,容器随便删;只要环境变量外置了,密钥就不会进 Git。下一步建议配合系统 cron 做定时备份,并把 docker-compose.yml 纳入版本管理,这样换服务器时真正能做到十几分钟恢复站点。
