Docker化MariaDb无法外部连接且阻塞后续容器启动问题
问题诊断与解决
核心问题分析
密码不一致导致健康检查失败
docker-compose中MYSQL_ROOT_PASSWORD设为Password123!@#,但Dockerfile和healthcheck命令里用的是Password123#@!,密码不匹配导致健康检查一直失败,依赖该服务的client_connector被阻塞无法启动。自定义entrypoint脚本逻辑错误
- 用
/etc/init.d/mariadb start &后台启动数据库后,立刻执行mariadb -u root -p$MYSQL_ROOT_PASSWORD < dump.sql,此时数据库尚未完成初始化,该命令会卡住,导致外部连接请求无限加载。 - 脚本中
while kill -0 $pid; do wait $pid; done的逻辑会无限等待数据库进程结束,后续的备份代码永远无法执行,且Docker无法正确管理前台进程。
分步修复方案
1. 统一密码配置
修改所有配置中的root密码为一致值,这里统一使用Password123!@#:
- Dockerfile:
FROM mariadb:11 COPY dump.sql /docker-entrypoint-initdb.d/ # 利用官方镜像自动初始化机制 ENV MYSQL_ROOT_PASSWORD=Password123!@# EXPOSE 3306 - docker-compose的healthcheck部分:
healthcheck: test: mysqladmin ping -h 127.0.0.1 -u root --password=Password123!@# start_period: 10s # 延长启动等待时间,给数据库初始化留足时间 interval: 5s timeout: 5s retries: 10
2. 重构entrypoint脚本
利用官方MariaDB镜像的原生机制,同时实现容器停止时的数据库备份:
#!/bin/bash # 创建备份目录(加-p避免目录已存在时报错) mkdir -p $BACKUP_DIR # 定义容器停止时执行的备份函数 backup_database() { echo "开始备份数据库 $DATABASE..." # 使用root用户执行备份(避免普通用户权限不足) mysqldump -u root -p$MYSQL_ROOT_PASSWORD $DATABASE > $BACKUP_DIR/$DATABASE.sql echo "数据库备份完成,文件路径:$BACKUP_DIR/$DATABASE.sql" } # 捕获容器停止信号(SIGTERM/SIGINT),触发备份 trap 'backup_database' SIGTERM SIGINT # 调用官方镜像的入口脚本,前台启动MariaDB(Docker需要前台进程来管理容器生命周期) exec docker-entrypoint.sh mysqld
3. 修正docker-compose配置
使用官方镜像的环境变量规范,确保服务正常启动:
version: "3" services: client_connector: build: ClientConnector/ command: python main.py ports: - 80:80 depends_on: mysql: condition: service_healthy mysql: build: Mysql/ environment: - MYSQL_ROOT_PASSWORD=Password123!@# - MYSQL_DATABASE=passwords # 官方变量,自动创建指定数据库 - BACKUP_DIR=/Database command: ./entrypoint.sh ports: - 8080:3306 healthcheck: test: mysqladmin ping -h 127.0.0.1 -u root --password=Password123!@# start_period: 10s interval: 5s timeout: 5s retries: 10
额外说明
- 官方MariaDB镜像会自动执行
/docker-entrypoint-initdb.d/目录下的SQL脚本,因此无需手动执行mariadb < dump.sql,镜像会在数据库首次初始化时自动加载。 - 用
exec命令启动官方入口脚本,确保MariaDB进程成为容器的PID 1,Docker可以正确捕获信号并管理容器生命周期。 - 如果需要创建普通数据库用户,使用官方提供的
MYSQL_USER和MYSQL_PASSWORD环境变量,避免自定义变量引发冲突。
内容的提问来源于stack exchange,提问作者bruh
相关产品推荐
相关产品推荐

