WordPress 用 Docker Compose 一键部署总报错?这 4 个高频坑和排查思路,我帮你踩平了

引言:别再手动配 LNMP 了,Compose 才是现代建站的正确打开方式

💡 推荐阅读:反向代理的终极形态:用 Docker 优雅落地 Nginx Proxy Manager,这才是内网穿透与多站点管理的正确姿势

很多站长在第一次接触 WordPress 时,习惯性去搜“如何安装 WordPress”,然后被一堆 LNMP 环境的编译教程劝退。其实,用 Docker Compose 做容器化部署,根本不需要在服务器上装 PHP、MySQL 或 Nginx,你只需要一个 YAML 文件,就能把整个 WordPress 运行环境拉起来。

但笔者发现,很多朋友在跟着网上的教程操作时,总是卡在“docker-compose up -d”这一步。要么是数据库连不上,要么是端口被占,要么是容器起来后页面空白。今天这篇文章,不聊那些顺风顺水的理想流程,专门把大家问得最多的 4 个高频报错 拿出来拆解,从根因到解决方案,一次性讲透。

Q1:执行 docker-compose up -d 后,WordPress 页面一直提示“Error establishing a database connection”,怎么办?

🔥 【限时特惠福利】高性价比独享云服务器限时 1 折起

搭建网站或部署容器推荐选择高稳定性独享云服务器。限时特惠通道开放中,点击即可领取专属满减代金券与特惠折扣:

👉 立刻领取云服务器限时优惠券

💡 延伸阅读:云服务器公网IP和私网IP傻傻分不清?端口配置踩坑实录,手把手教你一次搞定

根因剖析:这不是运气问题,是环境变量与容器生命周期的问题

这个报错几乎占了 WordPress 容器化部署问题的 50% 以上。绝大多数情况下,并不是你的数据库密码写错了,而是 WordPress 容器启动的速度比 MySQL 容器快,导致 WordPress 在初始化数据库连接时,MySQL 还没就绪。

另一个常见原因是:你在 docker-compose.yml 里写了 localhost 作为数据库主机名。注意,在容器世界里,localhost 指向的是容器自己,而不是宿主机,更不是 MySQL 容器。你应该使用服务名(service name),比如 db

解决方案:加上健康检查与依赖控制

不要再用 depends_on 这种简单的启动顺序控制了,我们需要让 WordPress 等 MySQL 真正“健康”了再启动。下面是笔者一直在用的一个稳妥配置:

version: '3.8'

services:
  db:
    image: mysql:8.0
    container_name: wp_db
    restart: always
    command: '--default-authentication-plugin=mysql_native_password'
    environment:
      MYSQL_ROOT_PASSWORD: rootpassword
      MYSQL_DATABASE: wordpress
      MYSQL_USER: wpuser
      MYSQL_PASSWORD: wppassword
    volumes:
      - db_data:/var/lib/mysql
    healthcheck:
      test: ["CMD", "mysqladmin", "ping", "-h", "localhost"]
      interval: 5s
      timeout: 5s
      retries: 20

  wordpress:
    depends_on:
      db:
        condition: service_healthy
    image: wordpress:latest
    container_name: wp_app
    restart: always
    ports:
      - "8080:80"
    environment:
      WORDPRESS_DB_HOST: db:3306
      WORDPRESS_DB_USER: wpuser
      WORDPRESS_DB_PASSWORD: wppassword
      WORDPRESS_DB_NAME: wordpress
    volumes:
      - wp_data:/var/www/html

volumes:
  db_data:
  wp_data:

注意看 healthcheckcondition: service_healthy 这两段。这样配置后,Compose 会等 MySQL 真正能接受连接后,才去启动 WordPress 容器,从根源上杜绝了连接超时问题。

预防建议:

  • 修改任何密码后,记得先执行 docker-compose down -v 清理旧卷,否则 MySQL 会沿用旧密码。
  • 如果你用的是 M1 芯片 Mac,MySQL 8.0 镜像建议加 platform: linux/x86_64,否则会有兼容性坑。

Q2:我想用域名加 HTTPS 访问,但容器里的 Nginx 配置总覆盖我的自定义配置,怎么办?

💡 深度技术指南:别再租第三方网盘了!手把手教你用 Docker 自建一套高可用私有云盘,彻底掌控数据主权

根因剖析:官方镜像的入口脚本会“强制”覆盖你的配置文件

WordPress 官方镜像在启动时,会执行内部的 docker-entrypoint.sh,它会将镜像内预置的 wp-config.php 和 Apache/Nginx 配置强制同步到挂载卷中。如果你直接把自定义的 .htaccess 或 Nginx 配置挂载到容器里,大概率会被覆盖掉。

解决方案:不要硬碰硬,换一个入口或者用环境变量注入

对于 Nginx 反向代理的需求,笔者更推荐 不要修改容器内的 Nginx 配置,而是在宿主机或单独的反代容器中处理 HTTPS。如果你的 WordPress 容器是直接暴露端口的,那么建议使用官方镜像支持的环境变量来开启 HTTPS 相关选项:

environment:
  WORDPRESS_CONFIG_EXTRA: |
    define('FORCE_SSL_ADMIN', true);
    if ($_SERVER['HTTP_X_FORWARDED_PROTO'] == 'https') $_SERVER['HTTPS'] = 'on';

如果你确实需要深度定制 Nginx 配置(比如调整上传大小限制),请使用 wordpress:php8.2-fpm-alpine 配合独立的 Nginx 容器,并把你的 default.conf 挂载到 /etc/nginx/conf.d/default.conf。此时不要挂载 WordPress 的 Apache 配置,避免冲突。

预防建议:

  • 把域名解析和 wp_option 表中的 siteurl 提前在数据库里改好,避免后台无法访问。
  • 如果只是内网测试,建议直接使用 IP 加端口访问,省去 HTTPS 的麻烦。

Q3:容器能启动,但上传主题或插件时提示“需要 FTP 访问凭据”,怎么破?

根因剖析:容器内 PHP 进程对挂载目录没有写权限

这是 Docker 部署 WordPress 时最典型的“权限幻觉”问题。你明明看到 wp-content 目录存在,但 PHP 就是写不进去。原因在于容器内的 www-data 用户(UID 33)对宿主机挂载的目录没有写权限,或者目录属主不对。

解决方案:修改目录属主或直接塞配置

最简单粗暴的方法,是在宿主机上执行一次属主修正:

# 假设你的 wp-content 挂载在 /opt/wordpress/wp-content
sudo chown -R 33:33 /opt/wordpress/wp-content

如果你不想折腾权限,也可以在 wp-config.php 里直接定义 FTP 方法为直写:

define('FS_METHOD', 'direct');

但请注意,这种方法要求 PHP 进程对目录有写权限,所以本质上还是要解决权限问题。建议在 Compose 文件中直接用 user: "33:33" 指定运行用户,从源头解决。

预防建议:

  • 不要使用 root 用户运行容器,虽然能解决权限问题,但会带来严重的安全隐患。
  • 在本地开发时,可以考虑 Bind Mount 挂载整个主题目录,方便实时调试。

Q4:为什么我用 docker-compose down 后,数据全没了?

根因剖析:你误用了 -v 参数,把数据卷一并删除了

这是很多新手最容易犯的致命错误。docker-compose down 只会停止并删除容器和网络,但不会删除数据卷。但如果你手滑加了 -v,Compose 会强制删除所有挂在 volumes: 下的数据卷,包括你的数据库文件。

解决方案:养成备份习惯,区分 down 和 down -v

请记住:除非你想彻底重置环境,否则永远不要使用 docker-compose down -v。如果你已经误删了,唯一的补救措施就是从备份中恢复。所以,请务必在宿主机上配置定时任务,定期导出数据库:

# 每天凌晨 3 点备份数据库
0 3 * * * docker exec wp_db sh -c 'exec mysqldump --all-databases -uroot -p"$MYSQL_ROOT_PASSWORD"' > /backup/wp_$(date +\%F).sql

预防建议:

  • db_datawp_data 卷改为挂载到宿主机具体目录(如 ./data/mysql),方便直接备份。
  • 在 Compose 文件中加入 container_name,避免容器重建后名称变化导致备份脚本失效。

补充:一套能直接上生产的 Compose 配置

为了让大家少走弯路,笔者把上面所有优化点整合成一套相对稳妥的生产级配置,包含资源限制和日志轮转。你可以直接复制使用:

version: '3.8'

services:
  db:
    image: mysql:8.0
    container_name: wp_db
    restart: always
    command: '--default-authentication-plugin=mysql_native_password'
    environment:
      MYSQL_ROOT_PASSWORD: ${DB_ROOT_PASSWORD}
      MYSQL_DATABASE: ${DB_NAME}
      MYSQL_USER: ${DB_USER}
      MYSQL_PASSWORD: ${DB_PASSWORD}
    volumes:
      - ./data/mysql:/var/lib/mysql
    healthcheck:
      test: ["CMD", "mysqladmin", "ping", "-h", "localhost"]
      interval: 5s
      timeout: 5s
      retries: 20
    deploy:
      resources:
        limits:
          memory: 512M

  wordpress:
    depends_on:
      db:
        condition: service_healthy
    image: wordpress:php8.2-apache
    container_name: wp_app
    restart: always
    ports:
      - "${WP_PORT:-8080}:80"
    environment:
      WORDPRESS_DB_HOST: db:3306
      WORDPRESS_DB_USER: ${DB_USER}
      WORDPRESS_DB_PASSWORD: ${DB_PASSWORD}
      WORDPRESS_DB_NAME: ${DB_NAME}
      WORDPRESS_CONFIG_EXTRA: |
        define('FS_METHOD', 'direct');
        define('WP_MEMORY_LIMIT', '256M');
    volumes:
      - ./data/wordpress:/var/www/html
    deploy:
      resources:
        limits:
          memory: 512M

使用 .env 文件来管理敏感信息,既安全又方便迁移。别忘了在 .gitignore 中忽略 .envdata 目录。

最后的建议

容器化部署 WordPress 的核心思路,是把数据库和应用解耦,把配置和镜像分离。当你理解了容器生命周期的概念,很多报错其实都能自己推断出原因。如果你准备在生产环境部署,建议选择一台 2核4G 以上的云服务器,并且一定要配置快照备份。域名方面,尽量选择正规注册商,并提前完成 ICP 备案,否则国内服务器无法绑定域名访问。

希望这篇文章能帮你把 Docker Compose 部署 WordPress 这条路彻底走通。如果你在实操中还有其他疑难杂症,欢迎在评论区留言,笔者看到后会尽力帮你排查。

相关技术专题与延伸阅读

📦 【资源免费领】本文全套实操配置文件与避坑手册下载

本文涉及的全套 Docker Compose 配置文件、服务器运维避坑清单及 AI 提效指令库已完整打包,可免费极速转存:

👉 点击前往夸克网盘免费极速转存(手机端领 1TB 空间)

💡 提示:推荐使用手机【夸克网盘 App】打开保存,新用户首月免费赠送 1TB 超大空间与免流量极速下载特权。

滚动至顶部