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
问题原因
- 用户访问权限限制:初始化脚本中创建的
${SQL_USER}和root用户仅允许localhost访问,而WordPress容器通过Docker网桥连接MariaDB,属于远程访问,不在localhost允许范围内,因此被拒绝连接。 - 数据库就绪状态未校验: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
相关产品推荐
相关产品推荐

