使用Docker Compose执行mongorestore时数据库连接失败求助
问题分析与解决方案
我一眼就看出问题的核心了:你在mongo-seed的Dockerfile里用RUN指令执行mongorestore,但**RUN是在镜像构建阶段运行的**,这时候你的Docker Compose还没启动任何服务,包括mongo容器,自然连不上任何Mongo服务。
为什么原来的配置不行?
Dockerfile里的RUN命令是在构建镜像的时候执行的,这个阶段和最终运行容器的环境完全隔离——此时mongo容器还没创建,服务网络也不存在,mongorestore根本找不到要连接的mongo:27017地址。
正确的解决方案
我们需要把mongorestore的逻辑放到容器启动阶段执行,同时还要加一步等待Mongo服务就绪的操作(因为容器启动有延迟,Mongo可能还没完全启动就被尝试连接)。
1. 修改mongo-seed/Dockerfile
把构建阶段只用来导出mLab的数据,然后用启动脚本处理恢复逻辑:
FROM mongo # 创建并赋予启动脚本执行权限 COPY seed.sh /seed.sh RUN chmod +x /seed.sh # 构建阶段从mLab导出数据(这一步不需要连接本地Mongo,没问题) RUN mongodump --uri=mongodb://xxxxxxxxxxxxx@xxxxxxxxxxxx:xxxxx/xxxxxx -o trapsdump # 容器启动时执行脚本 CMD ["/seed.sh"]
2. 在mongo-seed目录下创建seed.sh启动脚本
这个脚本会先等待Mongo服务就绪,再执行数据恢复:
#!/bin/bash # 循环等待Mongo服务可连接 until mongosh --host mongo:27017 --eval "db.adminCommand('ping')" >/dev/null 2>&1; do echo "Waiting for MongoDB to start..." sleep 2 done # 执行数据恢复 echo "MongoDB is ready, starting restore..." mongorestore /trapsdump/ --host mongo:27017 echo "Restore completed!"
3. 调整docker-compose.yml(可选优化)
Docker Compose v2+默认会为服务创建专属网络,links其实已经被更灵活的网络通信取代,你可以保留links,但也可以去掉——服务之间直接用服务名mongo就能通信:
version: "2" services: mongo: container_name: mongo image: mongo volumes: - ./data:/data/db ports: - "27017:27017" - "11990:11990" mongo-seed: build: ./mongo-seed depends_on: - mongo # 确保mongo先启动 app: container_name: traps restart: always build: . ports: - "3000:3000" depends_on: - mongo
补充说明
depends_on只会保证mongo容器先启动,但不会等待Mongo服务完全就绪,所以启动脚本里的等待逻辑是必须的。- 如果你的Mongo版本较老,
mongosh可能不存在,可以换成mongo命令:until mongo --host mongo:27017 --eval "db.adminCommand('ping')" >/dev/null 2>&1; do
内容的提问来源于stack exchange,提问作者Colin Richardson
相关产品推荐
相关产品推荐

