在Cloud Build中运行Docker镜像时PostgreSQL连接被拒绝
错误信息
psql: error: connection to server at "localhost" (127.0.0.1), port 5432 failed: Connection refused
Is the server running on that host and accepting TCP/IP connections?
connection to server at "localhost" (::1), port 5432 failed: Cannot assign requested address
Is the server running on that host and accepting TCP/IP connections?
环境配置
基础镜像Dockerfile (postgresql_utils_unit_test_python3.9)
FROM python:3.9-slim # install docker from https://docs.docker.com/engine/install/debian/ # required for postrgresql-utils unit testing RUN apt update -qq && \ apt install -y -qq postgresql libpq-dev python3-dev gcc ca-certificates curl gnupg lsb-release && \ mkdir -m 0755 -p /etc/apt/keyrings && \ curl -fsSL https://download.docker.com/linux/debian/gpg | gpg --dearmor -o /etc/apt/keyrings/docker.gpg && \ echo \ "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/debian $(lsb_release -cs) stable" \ | tee /etc/apt/sources.list.d/docker.list > /dev/null RUN apt update -qq && \ apt install -y -qq docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin
Cloud Build配置
steps: - id: test and build 3.9 name: postgresql_utils_unit_test_python3.9 script: | #!/bin/bash docker pull postgres docker run --detach --name pgsql-dev -e POSTGRES_PASSWORD=test1234 -e POSTGRES_DB=control_manager -p 3205:5432 postgres pip install . pip install -r tests/requirements.txt python -m pytest tests
PostgreSQL连接代码
connection = "user=postgres password=test1234 host=localhost port=3205 dbname=control_manager" db = connect(connection)
已尝试操作
- 通过
docker inspect -f '{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' <Container ID>获取容器IP替换localhost,连接失败 - 容器运行状态正常,
docker container ls输出:
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES d1247ce4db4c postgres "docker-entrypoint.s…" 2 seconds ago Up Less than a second 0.0.0.0:3205->5432/tcp, :::3205->5432/tcp pgsql-dev
- 容器内hosts文件:
127.0.0.1 localhost ::1 localhost ip6-localhost ip6-loopback fe00::0 ip6-localnet ff00::0 ip6-mcastprefix ff02::1 ip6-allnodes ff02::2 ip6-allrouters 172.17.0.3 d1247ce4db4c
1. 等待PostgreSQL服务就绪
Docker启动Postgres容器后,服务需要几秒初始化时间,直接运行测试会因服务未就绪导致连接失败。在docker run后添加等待逻辑:
# 等待Postgres服务可用 until docker exec pgsql-dev pg_isready -U postgres; do echo "等待PostgreSQL启动..." sleep 2 done
将这段代码插入到Cloud Build脚本的docker run之后,pip install之前。
2. 修正网络连接方式
在Cloud Build的Docker-in-Docker环境中,localhost指向的是运行测试的容器,而非Postgres容器,有两种修正方式:
方式一:用容器名直接连接
修改Python连接字符串,把host=localhost改成host=pgsql-dev,端口用容器内部的5432(无需端口映射,可去掉-p 3205:5432):
connection = "user=postgres password=test1234 host=pgsql-dev port=5432 dbname=control_manager" db = connect(connection)
方式二:用Docker主机IP连接
Docker-in-Docker环境中,Docker主机的IP通常是172.17.0.1,用这个IP替换localhost,端口用映射的3205:
connection = "user=postgres password=test1234 host=172.17.0.1 port=3205 dbname=control_manager" db = connect(connection)
3. 确保PostgreSQL允许外部连接
测试环境下,可在启动容器时添加POSTGRES_HOST_AUTH_METHOD=trust参数,避免连接权限问题:
docker run --detach --name pgsql-dev -e POSTGRES_PASSWORD=test1234 -e POSTGRES_DB=control_manager -e POSTGRES_HOST_AUTH_METHOD=trust postgres
内容的提问来源于stack exchange,提问作者Sean Conkie

