You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Docker Compose中WordPress容器无法连接MariaDB容器问题排查

WordPress无法连接MariaDB容器问题排查与解决

问题描述

通过Docker Compose部署了三个容器:WordPress+PHP、MariaDB和Nginx。可以正常访问localhost,但WordPress提示无法连接数据库,说明WordPress能通过Nginx对外提供服务,但无法跨容器连接到MariaDB。

错误信息

进入WordPress容器的shell手动尝试连接MariaDB时,出现以下错误:

$ mysql -u root -p123456789 -h mariadb base -P 3306
ERROR 2002 (HY000): Can't connect to MySQL server on '172.28.0.2' (115)

但进入MariaDB容器内部,用相同命令和凭据可以正常连接数据库。

MariaDB初始化脚本

if [ ! -d "/var/lib/mysql/mysql" ]; then
    mysql_install_db \
    --user=mysql \
    --datadir=/var/lib/mysql  \
    --port=3306 \
    --socket=/run/mysqld/mysqld.sock \
    --bind_address=* > /dev/null 2>&1

    service mysql start

    mysql -e "CREATE DATABASE IF NOT EXISTS \`${SQL_DATABASE}\`;"
    sleep 1

    mysql -e "CREATE USER IF NOT EXISTS \`${SQL_USER}\`@'localhost' IDENTIFIED BY 
    '${SQL_PASSWORD}';"
    sleep 1

    mysql -e "GRANT ALL PRIVILEGES ON \`${SQL_DATABASE}\`.* TO 
    \`${SQL_USER}\`@'localhost' IDENTIFIED BY '${SQL_PASSWORD}';"
    sleep 1

    mysql -e "ALTER USER 'root'@'localhost' IDENTIFIED BY '${SQL_ROOT_PASSWORD}';"
    sleep 1


    mysql -e "FLUSH PRIVILEGES;" -u root -p"$SQL_ROOT_PASSWORD"
    sleep 1

    mysqladmin --user=root --password=$SQL_ROOT_PASSWORD shutdown

    echo "Configuration finished."
else
    echo "Database doesn't exist."
fi

exec mysqld_safe

Docker Compose配置

version: '3'

services:
  mariadb:
    container_name: mariadb
    networks:
      - inception
    build:
      context: requirements/mariadb/
      dockerfile: Dockerfile
    env_file: .env
    volumes:
      - mariadb:/var/lib/mysql
    restart: unless-stopped
    ports:
      - "3306:3306"
  nginx:
    container_name: nginx
    volumes:
      - wordpress:/var/www/wordpress
    networks:
      - inception
    depends_on:
      - wordpress
    build: 
      context: requirements/nginx
      dockerfile: Dockerfile
    env_file: .env
    ports:
      - "443:443"
    restart: on-failure
  wordpress:
    container_name: wordpress
    env_file: .env
    volumes:
      - wordpress:/var/www/wordpress
    networks:
      - inception
    build: 
      context: requirements/wordpress
      dockerfile: Dockerfile
    depends_on:
      mariadb:
        condition: service_started
    restart: on-failure
    expose: 
      - "9000"

volumes:
  mariadb:
    driver: local
    driver_opts:
      type: 'none' 
      o: 'bind'
      device: '/${HOME}/Desktop/Inception/mariadb'
  wordpress:
    driver: local 
    driver_opts:
      type: 'none'
      o: 'bind'
      device: '/${HOME}/Desktop/Inception/wordpress'

networks:
  inception:
    driver: bridge 

问题原因

  1. 用户访问权限限制:初始化脚本中创建的${SQL_USER}和root用户仅允许localhost访问,而WordPress容器通过Docker网桥连接MariaDB,属于远程访问,不在localhost允许范围内,因此被拒绝连接。
  2. 数据库就绪状态未校验:WordPress的depends_on仅设置为service_started,但MariaDB容器启动后需要完成初始化才能接受连接,此时WordPress可能在数据库未就绪时发起连接,导致失败。

解决方案

1. 修改用户权限,允许远程访问

将初始化脚本中的用户创建和授权语句里的localhost替换为%(允许所有主机访问,测试环境可用),或指定Docker子网(比如错误信息中的172.28.0.%,生产环境更安全):

# 创建允许远程访问的普通用户
mysql -e "CREATE USER IF NOT EXISTS \`${SQL_USER}\`@'%' IDENTIFIED BY '${SQL_PASSWORD}';"
mysql -e "GRANT ALL PRIVILEGES ON \`${SQL_DATABASE}\`.* TO \`${SQL_USER}\`@'%' IDENTIFIED BY '${SQL_PASSWORD}';"

# 修改root用户允许远程访问(可选,不建议生产环境使用)
mysql -e "ALTER USER 'root'@'%' IDENTIFIED BY '${SQL_ROOT_PASSWORD}';"

2. 添加MariaDB健康检查,确保就绪后启动WordPress

在docker-compose.yml的mariadb服务中添加健康检查配置:

mariadb:
  # 原有配置不变
  healthcheck:
    test: ["CMD", "mysqladmin", "ping", "-h", "localhost", "-u", "root", "-p${SQL_ROOT_PASSWORD}"]
    interval: 5s
    timeout: 5s
    retries: 5

同时修改wordpress服务的depends_on条件:

wordpress:
  # 原有配置不变
  depends_on:
    mariadb:
      condition: service_healthy

3. 验证绑定地址

初始化脚本中mysql_install_db已经设置--bind_address=*,确保MariaDB监听所有网卡,此配置无需修改。

内容的提问来源于stack exchange,提问作者Samuel Janssens

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.24 19:40:27