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

Docker部署Golang后端+PostgreSQL+Redis连接问题求助

问题背景

我有一个包含Golang后端、PostgreSQL数据库和Redis的项目,用于初始化PostgreSQL的SQL如下:

ALTER USER postgres WITH password '123';

CREATE TABLE users
  (
     username VARCHAR (200) PRIMARY KEY,
     pass     VARCHAR (50)
  );

第一阶段:单Dockerfile多阶段构建问题

编写的Dockerfile如下:

# syntax=docker/dockerfile:1
FROM postgres:latest AS go2
ENV POSTGRES_USER postgres
ENV POSTGRES_PASSWORD ''
ENV POSTGRES_DB postgres
EXPOSE 5432
ADD table.sql /docker-entrypoint-initdb.d/
FROM redis:latest AS go3
FROM golang:latest AS go
WORKDIR /app
COPY . .
RUN go build -o bin
ENTRYPOINT [ "/app/bin" ] 
EXPOSE 8000

执行构建命令:

docker build . -t mycontainer

运行容器命令:

docker run -t mycontainer --network=bridge

出现错误:

[error] failed to initialize database, got error failed to connect to host=172.17.0.2 user=postgres database=postgres: dial error (dial tcp 172.17.0.2:5432: connect: connection refused)

尝试用docker run -t mycontainer --network=host运行,问题依旧。


第二阶段:Docker Compose更新后的问题

创建了docker-compose.yaml文件:

services:
  db:
    image: 'postgres:15.7'
    restart: always
    network_mode: bridge
    volumes:
      - './db/table.sql:/docker-entrypoint-initdb.d/init.sql'
    ports:
      - '5433:5432'
    environment:
      POSTGRES_DB: postgres
      POSTGRES_USER: postgres
      POSTGRES_PASSWORD: 123
  redis:
    image: 'redis:7.0.12'
    network_mode: bridge
    ports:
      - '6380:6379'
  backend:
    build: ./backend
    network_mode: bridge
    ports:
      - '8000:8089'
    depends_on:
      - db

现在PostgreSQL和Redis运行正常,但后端容器报错:

[error] failed to initialize database, got error failed to connect to host=127.0.0.1 user=postgres database=postgres: dial error (dial tcp 127.0.0.1:5433: connect: connection refused)


解决方案

1. 单Dockerfile多阶段构建的问题根源

多阶段构建中只有最后一个阶段(golang:latest)会被打包为最终镜像,postgres和redis阶段的内容不会被包含在最终容器内。也就是说你运行的容器只启动了Golang后端,PostgreSQL和Redis根本没在这个容器里运行,自然无法连接。

单容器运行多个服务不符合Docker最佳实践,应该用Docker Compose管理多个独立容器。

2. Docker Compose的连接问题修复

核心问题

  • 后端配置中用127.0.0.1:5433连接数据库:在Docker网络中,127.0.0.1指的是后端容器自身,而非PostgreSQL容器;且容器间通信应使用容器内部端口5432,而非宿主机映射的5433。
  • depends_on仅保证容器启动顺序,不确保PostgreSQL服务完全就绪(比如数据库初始化完成)。

修复步骤

步骤1:修改后端数据库连接地址

在Golang项目的数据库配置中,将连接地址改为db:5432:

  • db是Docker Compose中PostgreSQL服务的名称,Docker会自动解析为对应容器的IP。
  • 使用容器内部端口5432进行通信。

示例连接字符串:

dsn := "postgres://postgres:123@db:5432/postgres?sslmode=disable"
步骤2:优化Docker Compose网络配置

移除所有服务的network_mode: bridge,Docker Compose默认会创建专属桥接网络,更适合服务间通信。修改后的配置:

services:
  db:
    image: 'postgres:15.7'
    restart: always
    volumes:
      - './db/table.sql:/docker-entrypoint-initdb.d/init.sql'
    ports:
      - '5433:5432'
    environment:
      POSTGRES_DB: postgres
      POSTGRES_USER: postgres
      POSTGRES_PASSWORD: 123
  redis:
    image: 'redis:7.0.12'
    ports:
      - '6380:6379'
  backend:
    build: ./backend
    ports:
      - '8000:8089'
    depends_on:
      - db
步骤3:添加PostgreSQL就绪检查(可选)

为避免后端在PostgreSQL未完全就绪时连接失败,可为db服务添加健康检查:

services:
  db:
    # 保留原有配置
    healthcheck:
      test: ["CMD-SHELL", "pg_isready -U postgres -d postgres"]
      interval: 5s
      timeout: 5s
      retries: 5
  backend:
    # 保留原有配置
    depends_on:
      db:
        condition: service_healthy

3. 验证操作

  1. 停止并清理现有容器:
docker-compose down
  1. 重新构建并启动服务:
docker-compose up --build
  1. 查看后端日志,确认数据库连接成功。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.20 06:43:14