无法通过Docker Compose配置并执行Go语言数据库迁移求助
解决Docker Compose中Go服务数据库迁移失败的问题
你遇到的核心问题是Dockerfile中的RUN migrate命令是在镜像构建阶段执行的,此时db容器还未启动,也不在构建环境的网络中,自然无法解析db主机名。depends_on仅控制容器启动顺序,对镜像构建过程完全无影响。
具体解决方案
方案一:将迁移命令移到容器启动阶段执行
把迁移操作从镜像构建步骤改为容器启动时执行,确保此时db容器已运行且网络连通。
- 创建启动脚本
在vet-app-back目录下新建start.sh文件:
#!/bin/sh # 等待PostgreSQL服务就绪 until pg_isready -h db -p 5432 -U postgres; do echo "等待PostgreSQL启动..." sleep 2 done # 执行数据库迁移 migrate -path=./migrations -database="$VET_DB_DSN" up # 启动API服务 go run ./cmd/api
给脚本添加执行权限:
chmod +x start.sh
- 修改Dockerfile
FROM golang:1.19 WORKDIR /app ENV VET_DB_DSN=postgres://postgres:admin@db:5432/vet-app?sslmode=disable COPY go.mod go.sum ./ RUN go mod download COPY . ./ RUN curl -L https://github.com/golang-migrate/migrate/releases/download/v4.14.1/migrate.linux-amd64.tar.gz | tar xvz &&\ mv migrate.linux-amd64 $GOPATH/bin/migrate # 安装pg_isready用于检查PostgreSQL状态 RUN apt-get update && apt-get install -y postgresql-client # 替换启动命令为自定义脚本 CMD ["./start.sh"]
方案二:优化Docker Compose的依赖健康检查
通过健康检查确保back容器仅在db完全就绪后启动,避免数据库初始化未完成时执行迁移。
修改docker-compose.yaml:
services: db: image: postgres:9 ports: - 4321:5432 environment: - POSTGRES_DB=vet-app - POSTGRES_USER=postgres - POSTGRES_PASSWORD=admin healthcheck: test: ["CMD-SHELL", "pg_isready -U postgres -d vet-app"] interval: 2s timeout: 5s retries: 5 back: build: ./vet-app-back ports: - 8080:4000 depends_on: db: condition: service_healthy
关键注意事项
- 镜像构建阶段无法访问其他容器网络,所有依赖外部服务的操作必须放在容器启动阶段执行。
- PostgreSQL容器启动后,内部还需要时间完成数据库初始化,必须等待服务就绪后再执行迁移。
内容的提问来源于stack exchange,提问作者Nightspell
相关产品推荐
相关产品推荐

