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

Docker部署Django的Shell脚本中执行MySQL命令失败如何解决

Shell脚本启动Django关联MariaDB报错解决方案

根因说明

  1. 容器名不匹配:docker run 命令指定容器名为 db_name,但 docker exec 操作时误用了不存在的容器名 container_name,无法找到目标容器。
  2. MySQL服务未就绪:MariaDB容器启动后,内部数据库服务需要3-10秒完成初始化,脚本无等待逻辑直接执行后续操作,此时服务还未启动完成,自然无法连接。手动执行命令时存在天然操作间隔,刚好等到服务初始化完成,所以不会报错。
  3. 交互参数不适用脚本场景:docker exec 加了 -it 交互式终端参数,非交互式Shell脚本运行时没有分配终端,会导致执行失败。
  4. 特殊字符未转义:密码中的 $ 符号放在双引号内会被Shell识别为变量进行展开,导致实际传入数据库的密码和预期不符。
  5. 本地访问无端口映射:使用本地MySQL客户端连接容器内数据库时报错115,是因为启动MariaDB容器时没有做3306端口映射,宿主机网络无法直接访问容器内的数据库服务。

调整方案

  • 修正容器名,保证docker run和docker exec操作的是同一个容器
  • 增加MySQL服务就绪探测逻辑,等待服务完全启动后再执行建库建用户操作
  • 去掉docker exec的-it参数
  • 转义SQL语句中的$符号,避免Shell变量解析
  • 若使用本地客户端连接,启动容器时增加-p 3306:3306端口映射配置

修改后完整脚本

#!/bin/bash

# 启动MariaDB容器,如需本地访问可加上-p 3306:3306
docker run -e MYSQL_ROOT_PASSWORD=root --name db_name -d mariadb

# 等待MySQL服务就绪,最多重试30次
retry_cnt=30
until docker exec db_name mysql -u root -proot -e "select 1" > /dev/null 2>&1 || [ $retry_cnt -eq 0 ]
do
    echo "等待MySQL服务启动,剩余重试次数:$retry_cnt"
    sleep 1
    retry_cnt=$((retry_cnt-1))
done

if [ $retry_cnt -eq 0 ]; then
    echo "MySQL服务启动超时,请检查容器状态"
    exit 1
fi

# 执行建库建用户操作,转义密码中的$符号
docker exec db_name mysql -u root -proot -e "create database db_name CHARACTER SET UTF8;  CREATE USER invuser@XXX.17.0.3 IDENTIFIED BY 'root1234\$'; GRANT ALL PRIVILEGES ON db_name.* TO invuser@XXX.17.0.3 IDENTIFIED BY 'root1234\$';"

echo "Docker image name will be $1"

python3 manage.py makemigrations
python3 manage.py migrate

docker build . -t $1
docker run -d -p 8000:8000 $1

内容的提问来源于stack exchange,提问作者Sameer Atharkar

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.06 19:24:00