Docker容器执行PostgreSQL迁移报错:fatal: morestack on g0
解决Docker容器内PostgreSQL迁移报错“fatal: morestack on g0”
问题定位
报错“fatal: morestack on g0”是Go runtime底层错误,结合你的场景,核心原因集中在两点:
- 数据库连接地址配置错误,导致迁移工具无法正常连接触发异常
migrate工具的架构与容器运行环境不匹配(比如本地编译的amd64二进制放到arm64容器中运行)
不执行迁移时应用能正常构建,说明应用本身的编译和依赖无问题,问题仅出在迁移环节。
修复步骤
1. 修正数据库连接地址
你当前的DB_SOURCE使用localhost,但在Docker容器内,localhost指向容器自身,而非PostgreSQL所在容器。需替换为docker-compose中PostgreSQL服务的名称(假设服务名为db):
DB_SOURCE="postgresql://root:secret@db:5432/simple_bank?sslmode=disable"
2. 确保migrate工具与容器架构兼容
如果是本地编译的migrate二进制复制到容器中,大概率存在架构不兼容问题,推荐两种处理方式:
方式一:在容器内构建migrate
修改Dockerfile,直接在容器环境中编译对应架构的migrate:
# 构建阶段:编译migrate FROM golang:1.21-alpine AS migrate-builder RUN apk add --no-cache git RUN go install -tags 'postgres' github.com/golang-migrate/migrate/v4/cmd/migrate@latest # 运行阶段:复制migrate和应用 FROM alpine:3.18 RUN apk add --no-cache ca-certificates # 复制编译好的migrate COPY --from=migrate-builder /go/bin/migrate /app/migrate # 复制应用二进制和迁移文件 COPY your-app-binary /app/ COPY migration /app/migration/ COPY start.sh /app/ RUN chmod +x /app/start.sh WORKDIR /app CMD ["/app/start.sh"]
方式二:下载对应架构的预编译包
直接下载与容器架构匹配的预编译版本(以arm64为例):
FROM alpine:3.18 RUN apk add --no-cache ca-certificates wget # 下载arm64版本的migrate RUN wget -q https://github.com/golang-migrate/migrate/releases/download/v4.16.2/migrate.linux-arm64.tar.gz && \ tar xzf migrate.linux-arm64.tar.gz && \ mv migrate /app/migrate && \ rm migrate.linux-arm64.tar.gz LICENSE README.md # 后续复制应用和迁移文件步骤...
3. 确保PostgreSQL启动完成后再执行迁移
在docker-compose中加入健康检查,避免迁移命令在数据库未就绪时执行:
version: '3.8' services: db: image: postgres:15-alpine environment: POSTGRES_USER: root POSTGRES_PASSWORD: secret POSTGRES_DB: simple_bank volumes: - postgres_data:/var/lib/postgresql/data/ healthcheck: test: ["CMD-SHELL", "pg_isready -U root -d simple_bank"] interval: 5s timeout: 5s retries: 5 app: build: . environment: DB_SOURCE: "postgresql://root:secret@db:5432/simple_bank?sslmode=disable" depends_on: db: condition: service_healthy volumes: - ./migration:/app/migration volumes: postgres_data:
4. 修正start.sh脚本
确保脚本正确处理环境变量,避免引号解析问题:
#!/bin/sh set -e # 执行数据库迁移 /app/migrate -path /app/migration -database "$DB_SOURCE" -verbose up # 启动应用 exec /app/your-app-binary
验证操作
- 清理旧容器和数据卷:
docker-compose down -v - 重新构建并启动服务:
docker-compose up --build - 查看应用日志确认迁移成功:
docker-compose logs app
内容的提问来源于stack exchange,提问作者zaid saeed
相关产品推荐
相关产品推荐

