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

Docker Compose中postgres_container未在go_container前启动问题

问题

执行docker compose up时,按配置go_container通过depends_on依赖postgres_container,本该先启动PostgreSQL容器再启动Go容器,但实际Go容器先执行,PostgreSQL容器完全没启动。之前相同配置是正常的,修改后失效,重装Docker也无法解决。

相关配置文件

docker-compose.yml

version: '3.8'
services:
  go_container:
    container_name: go_container
    environment:
      - DATABASE_USER=${DATABASE_USER}
      - DATABASE_PASSWORD=${DATABASE_PASSWORD}
      - DATABASE_NAME=${DATABASE_NAME}
      - DATABASE_HOST=${DATABASE_HOST}
      - DATABASE_PORT=${DATABASE_PORT}
      - API_KEY=${API_KEY}
    build: .
    ports:
     - 8080:8080
    volumes:
      - .:/src
    depends_on:
      - postgres_container
    restart: on-failure
    networks:
      - weather
  postgres_container:
    container_name: postgres_container 
    user: postgres
    image: postgres:latest
    restart: always
    environment:
      - POSTGRES_USER=${DATABASE_USER}
      - POSTGRES_DB=${DATABASE_NAME}
      - POSTGRES_PASSWORD=${DATABASE_PASSWORD}
    ports:
      - 5432:5432
    volumes:
      - db_data:/var/lib/postgresql/data
      - ./sql/create.sql:/docker-entrypoint-initdb.d/create.sql
    healthcheck:
      test: ["CMD-SHELL", "pg_isready", "-U", "${DATABASE_USER}"]
    networks:
      - weather
volumes:
  db_data: {}
networks:
  weather:
    driver: bridge

Dockerfile

FROM golang:1.21.5

EXPOSE 8080

WORKDIR /src

COPY .env .

COPY . .

RUN go mod download && go mod verify

WORKDIR /src/cmd/app

RUN go run main.go

.env

DATABASE_HOST=postgres_container
DATABASE_PORT=5432
DATABASE_USER=postgres
DATABASE_PASSWORD=postgres
DATABASE_NAME=weather
SERVER_PORT=8080

问题原因

核心问题出在Dockerfile里的RUN go run main.go:

  • RUN是镜像构建阶段执行的命令,而非容器启动阶段。执行docker compose up时,会优先构建Go服务的镜像,构建过程中就会运行go run main.go尝试启动应用,此时PostgreSQL容器还未创建,必然连接失败,导致构建卡住或失败,后续PostgreSQL容器根本没机会启动,看起来就像是Go容器先执行、PostgreSQL没启动。

解决方案

  1. 修正Dockerfile的启动命令
    把RUN go run main.go替换为容器启动时执行的命令,比如CMD:
FROM golang:1.21.5

EXPOSE 8080

WORKDIR /src

COPY .env .

COPY . .

RUN go mod download && go mod verify

WORKDIR /src/cmd/app

CMD ["go", "run", "main.go"]

这样构建镜像时不会启动应用,只有当容器真正启动时才会运行Go服务,此时depends_on会保证PostgreSQL容器先启动。

  1. 增强依赖检查(可选但推荐)
    Docker Compose的depends_on仅保证容器启动顺序,不保证服务就绪。结合PostgreSQL的healthcheck,让Go容器等PostgreSQL服务真正就绪后再启动:
    修改docker-compose.yml中go_container的depends_on:
depends_on:
  postgres_container:
    condition: service_healthy
  1. 清理旧镜像并重新构建
    执行以下命令清理旧的镜像和容器,避免缓存影响:
docker compose down --rmi all
docker compose up --build

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.04 04:01:28