用Docker Compose部署WordPress网站

本例在一台允许建站的 Linux 服务器上,用 Compose 创建 WordPress 与 MySQL 两个服务。网站文件和数据库分别保存在命名卷中,数据库不发布公网端口,网站容器只监听本机 18080,由宿主机 Nginx 提供域名和 HTTPS。它是新建站点的步骤,不在已有 WordPress 数据卷上重新初始化。

准备独立目录和镜像

先按Docker Engine 与 Compose 安装教程准备容器环境,再安装 curl 和 openssl。住宅云不适用本教程。准备自己的域名,并按DNS教程指向当前服务器。确认 18080 没有被占用,且现有项目没有使用 baole-wp 这个 Compose 名称。下面目录已存在时请另选名称,不覆盖旧文件。

sudo docker compose version
sudo apt-get install curl openssl
sudo ss -ltnp 'sport = :18080'
sudo docker compose ls
mkdir -m 700 "$HOME/baole-wp"
cd "$HOME/baole-wp"
umask 077
mkdir -m 700 secrets
openssl rand -hex 24 > secrets/db_password.txt
openssl rand -hex 32 > secrets/db_root_password.txt
chmod 0444 secrets/db_password.txt secrets/db_root_password.txt

sudo docker pull wordpress:php8.3-apache
sudo docker pull mysql:8.4
BL_WP_REF=$(sudo docker image inspect --format '{{index .RepoDigests 0}}' wordpress:php8.3-apache)
BL_DB_REF=$(sudo docker image inspect --format '{{index .RepoDigests 0}}' mysql:8.4)
printf 'WP_IMAGE=%s\nDB_IMAGE=%s\n' "$BL_WP_REF" "$BL_DB_REF" > .env

只有两次拉取都成功才生成 .env,并核对两行都是带 @sha256: 的完整镜像引用。分支标签用于首次选取镜像,摘要用于固定本次部署;后续安全更新需要经过测试后主动更新摘要。PHP 8.3、MySQL 8.4 是本例的环境选择,部署已有程序前仍要核对主题和插件兼容性。

密码文件在宿主机上由权限为 700 的目录保护,文件本身只读,让被授予该 secret 的容器进程能够读取。Compose 的文件型 secret 不是磁盘加密保险箱;不要把项目目录放进网站根目录、公开仓库或公开下载区。

写入Compose文件

在当前目录创建 compose.yaml,粘贴以下内容并保存。YAML 使用空格缩进,不用 Tab;不要将 db 服务的 3306 端口映射到公网。

name: baole-wp
services:
  db:
    image: ${DB_IMAGE:?请先生成DB_IMAGE}
    restart: unless-stopped
    environment:
      MYSQL_DATABASE: wordpress
      MYSQL_USER: wp_app
      MYSQL_PASSWORD_FILE: /run/secrets/db_password
      MYSQL_ROOT_PASSWORD_FILE: /run/secrets/db_root_password
    secrets:
      - db_password
      - db_root_password
    volumes:
      - db_data:/var/lib/mysql
    healthcheck:
      test: ["CMD", "mysqladmin", "ping", "-h", "127.0.0.1", "--silent"]
      interval: 10s
      timeout: 5s
      retries: 12
      start_period: 40s

  wordpress:
    image: ${WP_IMAGE:?请先生成WP_IMAGE}
    restart: unless-stopped
    depends_on:
      db:
        condition: service_healthy
    ports:
      - "127.0.0.1:18080:80"
    environment:
      WORDPRESS_DB_HOST: db:3306
      WORDPRESS_DB_NAME: wordpress
      WORDPRESS_DB_USER: wp_app
      WORDPRESS_DB_PASSWORD_FILE: /run/secrets/db_password
    secrets:
      - db_password
    volumes:
      - wp_data:/var/www/html

secrets:
  db_password:
    file: ./secrets/db_password.txt
  db_root_password:
    file: ./secrets/db_root_password.txt

volumes:
  db_data:
  wp_data:
sudo docker compose config --quiet
sudo docker compose up -d --wait --wait-timeout 180
sudo docker compose ps
curl -I http://127.0.0.1:18080/

配置检查成功时不输出正文;它只证明文件能被解析。首次数据库初始化可能需要等待。db 显示 healthy、wordpress 显示运行中后,本机 HTTP 应返回响应,未安装的站点通常跳到安装页。数据库健康检查只检查进程是否响应,网站账号和数据库是否可用还要通过实际安装确认。

接上HTTPS,再完成中文安装

按Nginx反向代理教程为实际域名创建站点,目标设为 http://127.0.0.1:18080,再按HTTPS教程配置并检查证书。保留域名 Host 和实际访问协议,代理位置中至少要有下面几项:

location / {
    proxy_pass http://127.0.0.1:18080;
    proxy_set_header Host $host;
    proxy_set_header X-Forwarded-Proto $scheme;
    proxy_set_header X-Real-IP $remote_addr;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}

这段放在该域名实际使用的 Nginx server 块中,不能覆盖其他站点;修改后先运行 sudo nginx -t,通过后再重载。只通过该可信反向代理访问容器,避免客户端直接控制转发协议头。

在自己的电脑访问最终的 HTTPS 域名,确认证书和地址正确后,再选择简体中文、填写站点名称及管理员资料。不要先用 IP、localhost 或临时域名完成安装,否则后面可能需要调整站点地址。数据库连接资料已由 Compose 提供;若又出现数据库信息填写页,先检查镜像、挂载和配置,不重复创建数据库。

WordPress中文安装表单示例:站点标题、管理员账号、密码和电子邮箱
中文安装表单示例。填写站点标题、管理员账号、独立密码与邮箱,界面细节以安装版本为准。

完成标准与常见阻塞

  • 登录后台,发布一篇测试文章;上传一张测试图片,确认前台文章和媒体地址都使用最终的 HTTPS 域名。
  • 执行 sudo docker compose restart wordpress,然后重新访问文章和图片。两者保留只能证明这次重启正常,正式使用前还应安排文件、数据库的独立备份与恢复验证。
  • 出现数据库连接错误:查看 sudo docker compose logs --tail=80 db wordpress,核对 secret 文件可读、服务名是 db、库名和账号一致;提交日志前脱敏。
  • 修改密码文件后旧数据库仍拒绝连接:初始化环境变量只在空数据目录首次初始化时设置账号,改文件不等于改了已有数据库密码,需要同时按数据库流程变更账户和应用凭据。
  • 出现跳转循环或混合内容:先核对最终站点地址和 X-Forwarded-Proto,不用删除数据卷来修复 HTTPS。
  • 重启或更新后像全新网站:先查项目名和实际挂载卷,保留旧卷;不要执行带 -v 的 down,也不要反复安装覆盖现场。
WordPress前台测试文章示例,展示标题、正文和文章内图片
前台检查示例:核对文章标题、正文和图片,并点击固定链接重新访问。

这个镜像把 WordPress 文件放在 wp_data 卷内。更换容器镜像不能自动代表网站核心、主题和插件已经更新;维护时要分别记录容器环境版本与网站自身版本。MySQL 数据库备份可按MySQL导出与隔离恢复教程选择适合容器的连接方式,数据库文件不能靠在线复制数据目录代替一致性备份。

网站程序的后续维护可继续看WordPress核心、主题和插件升级与回退,分别核对容器环境、网站文件和数据库的版本。