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

如何在docker-compose down前自动执行MySQL数据库备份?

当然可以实现这种「down前钩子」的需求,你已经写了核心逻辑的脚本,接下来解决动态获取容器名的问题就很简单了,我给你几个实用的方案:

方案1:直接用docker-compose服务名(最推荐)

其实根本不需要硬编码容器名——docker-compose本身就支持通过服务名直接执行命令,不管容器实际叫什么(比如自动加的项目前缀)。假设你的docker-compose.yml里MySQL服务的名称是mysql(比如下面这样的配置):

services:
  mysql:
    image: mysql:8.0
    # 其他配置...

那你可以把脚本改成这样,直接用服务名替代固定容器名:

#!/bin/bash
CURRENT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"

# 用docker-compose exec + 服务名,无需硬编码容器名,-T避免终端交互问题
docker-compose exec -T mysql sh -c 'exec mysqldump --databases local -uroot -p"$MYSQL_ROOT_PASSWORD"' > "$CURRENT_DIR/docker/data/backup/local.sql"

# 可选:检查备份是否成功,再执行down
if [ $? -eq 0 ]; then
    echo "备份完成,正在停止服务..."
    docker-compose down
else
    echo "备份失败,取消停止服务操作"
    exit 1
fi

这个方案最省心,因为服务名是你自己在docker-compose.yml里定义的,不会随便变,而且docker-compose会自动找到对应的容器。

方案2:从docker-compose.yml动态提取服务名(更灵活)

如果你的MySQL服务名不是固定的mysql,或者想从配置文件自动读取,可以用yq(一款专门处理YAML的命令行工具)来提取服务名。

首先安装yq(不同系统安装方式不同,比如Ubuntu用apt install yq,macOS用brew install yq),然后修改脚本:

#!/bin/bash
CURRENT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"

# 从docker-compose.yml中提取包含"mysql"的服务名(适配类似db-mysql的命名)
MYSQL_SERVICE=$(yq e '.services | keys | .[] | select(. | test("mysql"))' "$CURRENT_DIR/docker-compose.yml")

docker-compose exec -T "$MYSQL_SERVICE" sh -c 'exec mysqldump --databases local -uroot -p"$MYSQL_ROOT_PASSWORD"' > "$CURRENT_DIR/docker/data/backup/local.sql"

docker-compose down

这个方案适合服务名可能变化的场景,自动匹配符合条件的服务。

方案3:通过docker-compose ps获取容器名

另一种思路是用docker-compose ps命令动态获取MySQL服务对应的容器名:

#!/bin/bash
CURRENT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"

# 获取mysql服务对应的容器ID/名称(-q参数只输出容器标识)
MYSQL_CONTAINER=$(docker-compose ps -q mysql)

docker exec "$MYSQL_CONTAINER" sh -c 'exec mysqldump --databases local -uroot -p"$MYSQL_ROOT_PASSWORD"' > "$CURRENT_DIR/docker/data/backup/local.sql"

docker-compose down

这个方法直接从运行中的容器列表里获取,适合需要容器名而非服务名的场景。

额外小贴士

  • 记得给down.sh添加执行权限:chmod +x down.sh,之后每次用./down.sh替代docker-compose down即可
  • 如果备份的数据库很大,建议加上--single-transaction参数(InnoDB引擎),避免锁表:mysqldump --single-transaction --databases local ...
  • 可以把备份文件按时间命名,避免覆盖:"$CURRENT_DIR/docker/data/backup/local_$(date +%Y%m%d_%H%M%S).sql"

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.28 03:27:45