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

Docker化MariaDb无法外部连接且阻塞后续容器启动问题

问题诊断与解决

核心问题分析

  1. 密码不一致导致健康检查失败
    docker-compose中MYSQL_ROOT_PASSWORD设为Password123!@#,但Dockerfile和healthcheck命令里用的是Password123#@!,密码不匹配导致健康检查一直失败,依赖该服务的client_connector被阻塞无法启动。

  2. 自定义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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.17 13:07:52