Shell脚本批量备份匹配Docker容器MongoDB报错求助
Docker容器MongoDB备份报错修复
报错原因定位
两个报错属于连锁触发的关联问题,并非独立故障:
- 第一阶段报错:
exec: "mongodump": executable file not found in $PATH
根因是当前匹配到的uBot_sandbox前缀业务容器为精简版应用镜像,没有预装MongoDB官方工具集(mongodump属于mongodb-database-tools组件),容器内PATH环境变量指向的路径下不存在该可执行文件,直接通过docker exec执行mongodump命令会直接失败。 - 第二阶段报错:
No such container:path: uBot_sandbox_subhrajp:/data/...
属于第一阶段失败的连锁反应:mongodump命令根本没有执行成功,容器内从未生成对应的备份目录,后续的docker cp命令自然找不到目标路径,触发路径不存在的报错。
可落地修复方案
推荐方案:零侵入式备份(无需修改原有业务容器)
放弃“在业务容器内部执行mongodump”的原有逻辑,改用官方MongoDB工具镜像作为临时执行节点,和目标容器共享网络栈完成备份,从根源上解决工具缺失、文件跨容器拷贝的问题:
- 不改动任何运行中的业务容器配置,不需要在容器内安装任何额外工具
- 临时工具容器和目标容器共享网络栈,可直接访问目标容器内部运行的MongoDB服务(默认27017端口),不需要额外开放端口、配置Docker网络
- 备份生成的文件直接通过目录挂载落到宿主机指定路径,跳过原流程中“容器内生成备份文件→docker cp拉取到宿主机”的冗余步骤
- 移除原脚本对已停止容器的遍历逻辑,仅处理运行中的匹配容器,避免无效操作
优化后可直接运行的脚本
#!/bin/bash set -uo pipefail # 固定配置参数 DATABASE_NAME="ubot-db" BACKUP_LOCATION="/home/UBOT" TIMESTAMP=$(date +'%Y_%m_%d_%H-%M-%S') # 根据实际环境调整MongoDB连接参数 MONGO_DEFAULT_PORT="27017" # 初始化宿主机备份根目录 mkdir -p "${BACKUP_LOCATION}" # 遍历所有名称匹配规则的运行中容器 for CONTAINER_NAME in $(docker ps --format "{{.Names}}" --filter "name=uBot_sandbox");do echo "=== 开始处理容器:${CONTAINER_NAME} ===" # 为每个容器创建独立的宿主机备份目录,避免文件冲突 CONTAINER_BACKUP_PATH="${BACKUP_LOCATION}/${CONTAINER_NAME}_${TIMESTAMP}" mkdir -p "${CONTAINER_BACKUP_PATH}" # 执行备份:使用官方mongo镜像的内置mongodump工具,和目标容器共享网络 docker run --rm \ --network "container:${CONTAINER_NAME}" \ -v "${CONTAINER_BACKUP_PATH}":/backup \ mongo:4.4 \ mongodump \ --uri="mongodb://127.0.0.1:${MONGO_DEFAULT_PORT}/${DATABASE_NAME}" \ --out=/backup # 校验执行结果,失败则清理空目录、继续处理下一个容器 if [ $? -eq 0 ]; then echo "容器 ${CONTAINER_NAME} 备份完成,存储路径:${CONTAINER_BACKUP_PATH}" else echo "容器 ${CONTAINER_NAME} 备份失败,已跳过该容器后续操作" rm -rf "${CONTAINER_BACKUP_PATH}" continue fi done
注意事项:
- 如果MongoDB设置了账号密码认证,只需要把mongodump的uri参数替换为带认证信息的格式即可,示例:
--uri="mongodb://用户名:密码@127.0.0.1:27017/${DATABASE_NAME}"- 如果MongoDB版本不是4.4,把临时工具镜像的tag替换为和业务环境MongoDB版本匹配的tag即可,避免工具版本不兼容
内容的提问来源于stack exchange,提问作者subhra_user
相关产品推荐
相关产品推荐

