在 NAS 上玩 Docker 的人,迟早会动"自己搭个博客"的念头。WordPress 需要 Web 服务和数据库两个容器配合,如果分别用 docker run 或图形界面一个个建,参数散落在各处,重装一次就要重新点一遍。Docker Compose 把整套服务写进一个 docker-compose.yml 文件,一条命令完成启动、停止和重建,以后换机器时整个文件夹拷走就行。
这篇文章假设你已经会用 Docker,拉镜像、建容器、映射端口这些概念不再解释,只聚焦 Compose 部分:从写配置文件、处理数据库连接,到用反向代理绑定域名,最终在 NAS 上跑起一个可用的 WordPress 站点。
规划目录结构
Compose 的习惯是一个项目一个文件夹。在 NAS 的共享文件夹里建一个专用目录,例如在 docker 共享文件夹下新建 wordpress 文件夹(文件夹名建议全小写,避免某些系统的路径识别问题),最终结构如下:
docker/wordpress/
├── docker-compose.yml # 手动创建
├── dbdata/ # 数据库文件,首次启动自动生成
└── html/ # WordPress 程序文件,首次启动自动生成不同品牌 NAS 的共享文件夹路径不一样(群晖常见的是 /volume1/docker/ 这种形式,其他系统请在文件管理器里确认实际路径),但后续操作完全一致。这套 Compose 文件本身与系统无关,群晖、威联通、绿联、飞牛都通用。部分系统的 Docker 应用里自带"项目"功能,可以直接在界面上粘贴 Compose 配置创建,效果和命令行相同,绿联官方的搭建指南就是这种做法。
编写 docker-compose.yml
在 wordpress 文件夹里新建 docker-compose.yml,内容如下:
version: '3.8'
services:
db:
image: mysql:8.0.36-oracle
container_name: wordpress-db
restart: unless-stopped
environment:
- MYSQL_DATABASE=wordpress
- MYSQL_ALLOW_EMPTY_PASSWORD=yes
- MYSQL_USER=wpuser
- MYSQL_PASSWORD=改成强密码
volumes:
- ./dbdata:/var/lib/mysql
networks:
- wordpress-network
wordpress:
image: wordpress
container_name: wordpress
restart: unless-stopped
depends_on:
- db
ports:
- "8080:80"
environment:
- WORDPRESS_DB_HOST=db:3306
- WORDPRESS_DB_NAME=wordpress
- WORDPRESS_DB_USER=wpuser
- WORDPRESS_DB_PASSWORD=改成强密码
volumes:
- ./html:/var/www/html
networks:
- wordpress-network
networks:
wordpress-network:这个文件定义了两个服务:db 跑 MySQL 8,wordpress 跑官方 WordPress 镜像(自带 PHP 运行环境和 Web 服务器)。两者挂在同一个内部网络 wordpress-network 下,可以通过服务名互相访问。restart: unless-stopped 让容器随 NAS 重启自动拉起。下面拆开讲三个最容易出错的配置项。
端口映射:只有 WordPress 需要
ports 的格式是"宿主机端口:容器端口"。示例把宿主机的 8080 映射到容器的 80,也就是通过 http://NAS的IP:8080 访问博客。之所以不用 80,是因为 NAS 的管理界面常常已经占用了 80 和 443,直接映射会冲突导致容器起不来,挑一个没被占用的高位端口即可。
注意 db 服务完全没有 ports 配置,这不是遗漏。两个容器在同一个内部网络里,WordPress 通过容器间通信访问数据库的 3306 端口,根本不需要把数据库暴露到宿主机。不映射数据库端口还能避免局域网里其他设备直接连库,安全性更好。
环境变量:两边必须对得上
环境变量是这套配置的核心,逻辑是"db 服务负责创建账号,wordpress 服务拿着同样的账号去连"。db 侧的 MYSQL_DATABASE、MYSQL_USER、MYSQL_PASSWORD 定义了首次启动时自动创建的数据库名、业务账号和密码;wordpress 侧的 WORDPRESS_DB_NAME、WORDPRESS_DB_USER、WORDPRESS_DB_PASSWORD 必须和上面逐项一致,包括大小写。
WORDPRESS_DB_HOST=db:3306 里的 db 就是 db 服务的服务名,Compose 的内部网络会自动把服务名解析成对应容器的 IP,后面的 3306 是容器内部端口,和宿主机没有任何关系。
示例里 MYSQL_ALLOW_EMPTY_PASSWORD=yes 表示 root 账户不设密码。这能接受的唯一前提是数据库端口没有暴露到宿主机,root 只在容器内部可用。如果你后续想把数据库映射出来给局域网里的其他工具连接,请先查阅 MySQL 镜像文档为 root 设置密码,并删掉这个空密码选项。
卷挂载:数据落在哪,备份就备哪
volumes 使用相对路径的绑定挂载:./dbdata 对应容器内 MySQL 的数据目录 /var/lib/mysql,./html 对应 WordPress 的程序目录 /var/www/html。前者存所有数据库表;后者是 WordPress 的完整安装目录,主题、插件、上传的图片全在里面。
这样挂载的好处是数据持久化在宿主机文件夹里:容器删除、重建、升级,只要这两个文件夹还在,站点就完整无损。以后要备份博客,直接打包整个 wordpress 文件夹即可。首次启动时 Docker 会自动创建这两个目录并完成初始化,不需要手动建。
启动并完成首次登录
通过 SSH 进入项目目录,执行:
cd /volume1/docker/wordpress # 换成你的实际路径
docker-compose up -d-d 表示后台运行。拉取镜像和初始化需要几分钟,之后用 docker-compose ps 查看,db 和 wordpress 两个服务都应该是 running 状态。
首次启动时 MySQL 要初始化数据文件,耗时较长,WordPress 容器可能会先报几次数据库连接失败再自动恢复,这是正常现象。稍等片刻,浏览器访问 http://NAS的IP:8080,就能看到 WordPress 的安装向导:选语言、填站点标题、设置管理员账号和密码。因为数据库信息已经通过环境变量配好,向导不会再问数据库连接信息,填完即可登录后台。
数据库连接失败怎么排查
如果访问时一直提示建立数据库连接失败,按下面的顺序检查,绝大多数问题都出在这几处。
第一,检查 WORDPRESS_DB_HOST 是否写成了 127.0.0.1 或 localhost。这是新手最常见的错误:每个容器都有自己独立的网络环境,WordPress 容器里的 localhost 指向它自己,而数据库在另一个容器里,这样永远连不上。正确写法就是服务名 db:3306。同理,也不要随手填 NAS 的局域网 IP 加端口——除非你确实把数据库端口映射到了宿主机,否则容器之间用服务名直连最可靠。
第二,核对两组环境变量是否完全一致。WORDPRESS_DB_USER 和 WORDPRESS_DB_PASSWORD 必须与 db 服务的 MYSQL_USER、MYSQL_PASSWORD 一字不差。改完配置后要重新执行 docker-compose up -d 让改动生效。
第三,给数据库一点初始化时间。depends_on 只保证 db 容器先启动,并不等 MySQL 完成初始化。首次部署如果在启动后立刻访问看到连接错误,等一两分钟再刷新,很可能自己就恢复了。
第四,注意"改密码不生效"的坑。MySQL 容器只在数据目录为空时执行初始化,MYSQL_USER 和 MYSQL_PASSWORD 只在第一次启动时写入数据库。站点跑起来之后如果你修改了 Compose 文件里的密码,旧数据里存的还是旧密码,WordPress 拿着新密码去连就会被拒绝。解决办法是要么把密码改回去,要么确认数据可以丢弃后清空 dbdata 文件夹再重新初始化。
如果以上都对还是不行,可以在 NAS 的 Docker 管理界面查看 db 容器的日志,确认 MySQL 是否正常启动;也可以临时部署一个 phpMyAdmin 容器挂在同一网络下,用同样的账号密码试连,快速定位是账号问题还是服务问题。另外,不少 NAS 教程会选择 MariaDB 作为数据库,如果你在 MySQL 8 上反复卡住,换成 MariaDB 也是一条可行的路。
用反向代理绑定域名
IP 加端口的地址自己用没问题,但要让博客正式对外,还是需要域名和 HTTPS。整体链路是:域名解析到你的公网 IP(家庭宽带的 IP 经常变化,通常要配合 DDNS 动态域名服务),路由器上做端口转发把外部请求转到 NAS,再由 NAS 上的反向代理按域名把请求分发给本机的 8080 端口。
反向代理本身有多种实现方式,按省事程度选:
- 部分 NAS 系统自带反向代理功能,在控制面板里填域名和目标端口即可,不需要自己写配置;
- 想完全自己掌控,可以再跑一个 Nginx 容器做反向代理,配合 Let's Encrypt 申请免费证书并用定时任务自动续期,DigitalOcean 的这篇教程完整演示了这套组合;
- 不想在路由器上开放任何端口,可以考虑 Cloudflare Tunnel 这类方案,让 NAS 主动建立到 Cloudflare 的出站连接,流量经 Cloudflare 网络回源到本地服务。
这里不展开 Nginx 的具体配置,只提醒两个和 WordPress 相关的点。一是反向代理的目标地址填 127.0.0.1:8080 即可,因为 WordPress 容器已经把端口映射到了宿主机。二是域名生效后,记得登录后台,在"设置 → 常规"里把 WordPress 地址和站点地址都改成 https://你的域名,否则上传的图片等资源可能仍走旧的 IP 地址,浏览器会报混合内容错误。
到这里,一个跑在 NAS 上的 WordPress 就部署完成了。日常维护记住三件事:备份就是打包 wordpress 项目文件夹;升级镜像时拉取新镜像后重新执行 docker-compose up -d,数据目录不受影响;如果哪天想换 NAS,整个文件夹拷过去再启动一次,站点就原样复活——这正是用 Compose 管理服务的意义。

评论(1)
正准备在NAS上搭博客,这篇来得真及时