继上一篇分享解决 WordPress Docker 容器在我 NAS 上突然 “Unhealthy” 的经历后,今天,我就将上次的 WordPress 站点从我的群晖 NAS 迁移到搬瓦工(Bandwagon Host)的 Rocky Linux VPS,并配置 Nginx 反向代理及 Cloudflare CDN 的完整过程记录下来,希望能给大家提供一份详尽的参考。AI 助手依然是完成这次工程的得力伙伴。
迁移目标
- 将 NAS Docker 环境中的 WordPress 站点(文件和数据库)完整迁移到搬瓦工 VPS。
- 在 VPS 上使用 Docker Compose 部署 WordPress、MariaDB、phpMyAdmin。
- 引入 Nginx 作为反向代理,并配置 SSL (HTTPS)。
- 集成 Cloudflare CDN 进行加速和安全防护。
- 确保所有 Docker 服务最终都处于
healthy状态。
阶段一: 在 NAS 上准备迁移数据
迁移前,务必对现有 WordPress 站点进行完整备份。
1. 备份 WordPress 文件
包含所有核心文件、wp-content 目录及 wp-config.php
# 进入wordpress所在目录 cd /volume1/docker/
# 将 wordpress 目录打包并压缩,YYYYMMDD 替换为当天日期 sudo tar -czvf wordpress_nas_backup_20250518.tar.gz wordpress/
2. 备份 WordPress 数据库
- 通过 NAS 上的 phpMyAdmin(
http://<你的NAS_IP>:2500)登录。 - 选择数据库(如
leogaoxhosting_db), - 选择“快速 (Quick)”导出方法,格式 SQL。
- 点击“导出 (Export)”。


阶段二: 在搬瓦工 VPS (Rocky Linux) 上准备新家
1. 清理 VPS(如果非全新)
# 停止并移除旧容器 sudo docker stop old_nginx old_wp old_db sudo docker rm old_nginx old_wp old_db # 清理卷和网络 sudo docker volume prune -f sudo docker network prune -f # 删除旧部署文件夹(谨慎操作) sudo rm -rf /path/to/old_deployment_folder
2. 安装/确认 Docker & Docker Compose
sudo docker --version # 示例: Docker version 28.1.1, build 4eba377 sudo systemctl status docker # ● docker.service … Active: active (running) docker compose version # 示例: Docker Compose version v2.35.1
3. 创建目录结构
sudo mkdir -p /srv/docker/wordpress_vps/html sudo mkdir -p /srv/docker/wordpress_vps/db sudo mkdir -p /srv/docker/wordpress_vps/nginx/conf.d sudo mkdir -p /srv/docker/wordpress_vps/nginx/certs sudo mkdir -p /srv/docker/wordpress_vps/nginx/logs sudo mkdir -p /srv/docker/wordpress_vps/secrets
4. 配置防火墙 (firewalld)
sudo firewall-cmd --permanent --add-service=http sudo firewall-cmd --permanent --add-service=https sudo firewall-cmd --reload
阶段三: 迁移数据
1. 上传备份文件到 VPS 的 worpress_vps 所在文件夹
wordpress_nas_backup_20250518.tar.gz 和 leogaoxhosting_db.sql 上传至 /srv/docker/wordpress_vps/。
2. 恢复 WordPress 文件
cd /srv/docker/wordpress_vps/
# 解压并去掉多余目录
sudo tar -xzvf wordpress_nas_backup_20250518.tar.gz -C html/ --strip-components=1
# 设置所有权与权限 (UID/GID=33)
sudo chown -R 33:33 /srv/docker/wordpress_vps/html/
sudo find /srv/docker/wordpress_vps/html/ -type d -exec chmod 755 {} \;
sudo find /srv/docker/wordpress_vps/html/ -type f -exec chmod 644 {} \;
# 对 wp-config.php 设置更严格权限
sudo chmod 600 /srv/docker/wordpress_vps/html/wp-config.php
阶段四:核心配置(此阶段也是整个迁移的难点所在)
1. 在 /srv/docker/wordpress_vps/secrets/ 目录下安全地创建两个密码文件:wordpress_db_password.txt 和 mariadb_root_password.txt
cd /srv/docker/wordpress_vps/ sudo chmod 700 secrets echo 'YOUR_WORDPRESS_DB_PASSWORD' | sudo tee secrets/wordpress_db_password.txt > /dev/null sudo chmod 600 secrets/wordpress_db_password.txt echo 'YOUR_MARIADB_ROOT_PASSWORD' | sudo tee secrets/mariadb_root_password.txt > /dev/null sudo chmod 600 secrets/mariadb_root_password.txt
2. 编写 docker-compose.yml
networks:
app_network:
driver: bridge
services:
nginx:
image: nginx:1.27-alpine
container_name: wordpress_nginx_proxy
ports:
- "80:80"
- "443:443"
volumes:
- ./nginx/conf.d:/etc/nginx/conf.d:ro
- ./nginx/certs:/etc/nginx/certs:ro
- ./html:/var/www/html:ro
- ./nginx/logs:/var/log/nginx
networks:
- app_network
depends_on:
- wordpress
restart: unless-stopped
wordpress:
image: wordpress:6.8.1-php8.2-apache
container_name: WordPress_VPS
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:80/"]
interval: 30s
timeout: 10s
retries: 5
depends_on:
db:
condition: service_healthy
volumes:
- ./html:/var/www/html:rw
- ./secrets/wordpress_db_password.txt:/run/secrets/wp_db_password:ro
environment:
WORDPRESS_DB_HOST: wordpress_db_vps_hostname
WORDPRESS_DB_USER: leogaox
WORDPRESS_DB_PASSWORD_FILE: /run/secrets/wp_db_password
WORDPRESS_DB_NAME: leogaoxhosting_db
WORDPRESS_TABLE_PREFIX: wp_
networks:
- app_network
restart: on-failure:5
db:
image: mariadb:11.3-jammy
container_name: WordPress_DB_VPS
healthcheck:
test: ["CMD-SHELL","healthcheck.sh --su-mysql --connect"]
interval: 30s
timeout: 20s
retries: 3
start_period: 90s
environment:
MYSQL_DATABASE: leogaoxhosting_db
MYSQL_USER: leogaox
MYSQL_PASSWORD_FILE: /run/secrets/db_user_password
MYSQL_ROOT_PASSWORD_FILE: /run/secrets/db_root_password
TZ: Asia/Shanghai
volumes:
- ./db:/var/lib/mysql:rw
- ./secrets/wordpress_db_password.txt:/run/secrets/db_user_password:ro
- ./secrets/mariadb_root_password.txt:/run/secrets/db_root_password:ro
networks:
- app_network
restart: on-failure:5
phpmyadmin:
image: phpmyadmin:5.2
container_name: WordPress_phpMyAdmin_VPS
ports:
- - "127.0.0.1:2500:80" # <--- 限制只能本地访问
environment:
PMA_HOST: wordpress_db_vps_hostname
PMA_PORT: 3306
networks:
- app_network
depends_on:
db:
condition: service_healthy
restart: on-failure:5
3. Nginx 反向代理配置
把从 Cloudflare 下载的证书放入 /srv/docker/wordpress_vps/nginx/certs下,在/srv/docker/wordpress_vps/nginx/conf.d/ 目录下创建 Nginx 配置文件,命名为 wordpress_vps.conf
server {
listen 80;
listen [::]:80;
# 改成你的域名
server_name leogaox.com www.leogaox.com;
location / {
return 301 https://$host$request_uri;
}
}
server {
listen 443 ssl http2;
listen [::]:443 ssl http2;
#改成你的域名
server_name leogaox.com www.leogaox.com;
ssl_certificate /etc/nginx/certs/leogaox.com.pem;
ssl_certificate_key /etc/nginx/certs/leogaox.com.key;
# 推荐启用的 SSL 配置
ssl_protocols TLSv1.2 TLSv1.3;
# 从 Mozilla SSL Configuration Generator 获取推荐的加密套件,以下是一个示例:
ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384;
ssl_prefer_server_ciphers off;
ssl_session_timeout 1d;
ssl_session_cache shared:SSL:10m; # 约40000个会话
ssl_session_tickets off; # 增强前向保密性
# 如果您使用的是 Cloudflare Origin CA 证书,OCSP Stapling 可能由 Cloudflare 处理或不需要
# 如果是其他证书,建议配置 OCSP Stapling
# ssl_stapling on;
# ssl_stapling_verify on;
# resolver 1.1.1.1 1.0.0.1 8.8.8.8 8.8.4.4 208.67.222.222 208.67.220.220 valid=300s; # 使用多个DNS解析器
# resolver_timeout 5s;
# 可选:添加 HSTS 头部 (强制浏览器使用HTTPS,测试无误后再启用)
# add_header Strict-Transport-Security "max-age=63072000; includeSubDomains; preload" always;
access_log /var/log/nginx/wordpress_access.log;
error_log /var/log/nginx/wordpress_error.log;
# 从 Cloudflare 获取真实 IP (请务必从官方链接更新此列表)
# IPv4: https://www.cloudflare.com/ips-v4
# IPv6: https://www.cloudflare.com/ips-v6
set_real_ip_from 173.245.48.0/20;
set_real_ip_from 103.21.244.0/22;
set_real_ip_from 103.22.200.0/22;
set_real_ip_from 103.31.4.0/22;
set_real_ip_from 141.101.64.0/18;
set_real_ip_from 108.162.192.0/18;
set_real_ip_from 190.93.240.0/20;
set_real_ip_from 188.114.96.0/20;
set_real_ip_from 197.234.240.0/22;
set_real_ip_from 198.41.128.0/17;
set_real_ip_from 162.158.0.0/15;
set_real_ip_from 104.16.0.0/13;
set_real_ip_from 104.24.0.0/14;
set_real_ip_from 172.64.0.0/13;
set_real_ip_from 131.0.72.0/22;
set_real_ip_from 2400:cb00::/32;
set_real_ip_from 2606:4700::/32;
set_real_ip_from 2803:f800::/32;
set_real_ip_from 2405:b500::/32;
set_real_ip_from 2405:8100::/32;
set_real_ip_from 2a06:98c0::/29;
set_real_ip_from 2c0f:f248::/32;
real_ip_header CF-Connecting-IP;
location / {
proxy_pass http://wordpress_vps_hostname:80;
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;
proxy_set_header X-Forwarded-Host $host;
proxy_set_header X-Forwarded-Port $server_port;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade"; # 用于 WebSocket 等协议的升级
proxy_read_timeout 86400s; # Nginx 1.7.7+ 使用 's' 后缀
proxy_send_timeout 600s; # (新增) 发送超时
proxy_connect_timeout 600s;# (新增) 连接超时
client_max_body_size 64M; # 调整为一个更合理的值,除非您确实需要上传非常大的文件
}
# (可选) 如果您想通过 Nginx 代理 phpMyAdmin (例如通过 yourdomain.com/pma)
# location /pma { # 使用一个不容易被猜到的路径,并确保末尾没有斜杠
# rewrite ^/pma(/.*)$ $1 break; # 移除 /pma 前缀
# proxy_pass http://wordpress_phpmyadmin_vps_hostname:80; # 指向 phpMyAdmin 服务的 hostname 和内部端口
# 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;
# }
}
阶段四:启动服务
1. 拉取镜像并启动
cd /srv/docker/wordpress_vps/ sudo docker compose pull sudo docker compose up -d --force-recreate --remove-orphans
2. 检查服务状态
sudo docker compose ps # 确认所有容器均为 Up 或 healthy
阶段五:Cloudflare 配置与最终测试
- 在 Cloudflare DNS 中,将
leogaox.comA 记录指向 VPS 公共 IP,设置为 已代理 (Proxied)。 - 在 SSL/TLS 选项中,选择 Full (Strict) 模式。
- 浏览器访问 https://leogaox.com 并验证站点正常。



阶段六:经验总结
至此就完成了博客从 NAS 到 VPS 的迁移。迁移的最大难点在阶段四,要准备和编写好几个文件,特别是compose.yml和ngnix.conf这两个文件,如果后面容器运行报错,多半和这两个文件有关。希望这篇文章对大家有所帮助!