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

Python Postgres Testcontainer在GitLab CI流水线中连接失败

GitLab CI中Testcontainers Python连接Postgres超时问题解决

问题描述

  • 本地及其他本地机器上,使用Testcontainers Python启动Postgres容器(镜像postgres:14.7)可正常连接数据库
  • GitLab CI流水线中,容器已确认启动(可查看日志),但始终卡在Waiting to be ready...阶段,底层报错:

sqlalchemy.exc.OperationalError: (psycopg2.OperationalError) could not connect to server: Connection timed out
Is the server running on host "172.17.0.1" and accepting TCP/IP connections on port 49269?

启动容器代码:

with PostgresContainer(image="postgres:14.7", dbname="postgres", port=5432) as postgres:
    print(f"Postgres started on port {postgres.get_connection_url()}")
    yield create_engine(postgres.get_connection_url(), echo=False)

已尝试操作:

  • 更换连接host为localhost、网关/网桥IP
  • 排查所有日志未获有效信息
  • 确认GitLab Runner无问题(同Runner上的C#项目使用Testcontainers正常)

解决方案

1. 强制Testcontainers使用localhost作为连接host

在GitLab CI配置中添加环境变量,让Testcontainers生成的连接URL自动替换host为localhost(适配CI环境的网络映射逻辑):

# .gitlab-ci.yml 示例
test:
  stage: test
  services:
    - name: docker:dind
  variables:
    DOCKER_HOST: tcp://docker:2375
    DOCKER_DRIVER: overlay2
    TESTCONTAINERS_HOST_OVERRIDE: "localhost"  # 关键配置
  script:
    - pip install -r requirements.txt
    - pytest

2. 修改代码适配CI网络

如果环境变量配置无效,可手动修改连接URL的host,并确保容器监听所有地址:

from testcontainers.postgres import PostgresContainer

with PostgresContainer(
    image="postgres:14.7",
    dbname="postgres",
    port=5432,
    command=["postgres", "-c", "listen_addresses='*'"]  # 让Postgres监听所有IP
) as postgres:
    # 替换连接URL中的网关IP为localhost
    conn_url = postgres.get_connection_url().replace("172.17.0.1", "localhost")
    print(f"Postgres started on port {conn_url}")
    yield create_engine(conn_url, echo=False)

3. 延长容器启动等待时间

CI环境资源可能受限,默认等待时间不足导致超时,可延长超时阈值:

with PostgresContainer(
    image="postgres:14.7",
    dbname="postgres",
    port=5432,
    start_timeout=120  # 延长至120秒
) as postgres:
    print(f"Postgres started on port {postgres.get_connection_url()}")
    yield create_engine(postgres.get_connection_url(), echo=False)

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.23 09:02:14