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

如何让Docker中的Python项目通过docker-compose访问本地PostgreSQL数据库

问题:Docker容器中Python脚本无法连接PostgreSQL数据库

背景

本地调试Python主脚本时,数据库连接函数可正常工作,但将项目通过Dockerfile和docker-compose打包进容器后,无法建立数据库连接。

数据库连接函数

# 创建数据库连接
def create_connection(host, dbname, user, password):
    print(host, dbname, user, password)
    try:
        conn = psycopg2.connect("host={} dbname={} user={} password={}".format(host, dbname, user, password))
        conn.set_session(autocommit=True)
    except psycopg2.Error as e:
        print("Error: Could not make connection to the Postgres database")
        print(e)

    # 使用连接获取可执行查询的游标
    try:
        cur = conn.cursor()
    except psycopg2.Error as e:
        print("Error: Could not get cursor to the Database")
        print(e) 

    return conn, cur

错误信息

Error: Could not make connection to the Postgres database
connection to server at "127.0.0.1", port 5432 failed: Connection refused
    Is the server running on that host and accepting TCP/IP connections?

当前docker-compose.yml配置

version: '3.4'

networks:
  network1:
    name: my-network
    attachable: true
    ipam:
      driver: default
      config:
        - subnet: 172.18.0.0/16
          ip_range: 172.18.5.0/24
          gateway: 172.18.0.1

services:
  tft:
    image: tft
    build:
      context: .
      dockerfile: ./Dockerfile
    network_mode: host
    postgres:
      image: postgres:14.1-bullseye
      environment:
        POSTGRES_PASSWORD: "*********"
      ports:
        - "5433:5432"
      networks:
        - network1
      extra_hosts:
        - "host.docker.internal:host-gateway"

问题根源与修复方案

核心问题

  1. 网络环境不互通:tft服务使用network_mode: host(直接使用宿主机网络),而postgres服务在自定义的network1网络中,两者不在同一网络域,无法直接通信。
  2. 连接地址错误:脚本中使用127.0.0.1:5432,容器内的127.0.0.1指向容器自身,而非宿主机或PostgreSQL容器;同时PostgreSQL容器映射的宿主机端口是5433,和脚本中的5432不匹配。

推荐修复方案(统一自定义网络)

修改docker-compose.yml,让tft服务加入自定义网络,移除network_mode: host:

version: '3.4'

networks:
  network1:
    name: my-network
    attachable: true
    ipam:
      driver: default
      config:
        - subnet: 172.18.0.0/16
          ip_range: 172.18.5.0/24
          gateway: 172.18.0.1

services:
  tft:
    image: tft
    build:
      context: .
      dockerfile: ./Dockerfile
    networks:
      - network1  # 加入自定义网络,和postgres处于同一网络
    depends_on:
      - postgres  # 确保postgres启动后再启动tft
  postgres:
    image: postgres:14.1-bullseye
    environment:
      POSTGRES_PASSWORD: "*********"
      POSTGRES_DB: your_db_name  # 显式指定数据库名,和脚本参数一致
      POSTGRES_USER: your_db_user  # 显式指定用户名,和脚本参数一致
    ports:
      - "5433:5432"
    networks:
      - network1

同时修改Python脚本的连接参数,将host设置为postgres(Docker Compose的服务名,会自动解析为容器IP),端口使用容器内部的5432:

# 调用示例
conn, cur = create_connection(
    host="postgres", 
    dbname="your_db_name", 
    user="your_db_user", 
    password="*********"
)

备选方案(保留host网络模式)

若必须使用network_mode: host,则修改postgres服务也使用host网络:

services:
  tft:
    image: tft
    build:
      context: .
      dockerfile: ./Dockerfile
    network_mode: host
  postgres:
    image: postgres:14.1-bullseye
    environment:
      POSTGRES_PASSWORD: "*********"
    network_mode: host  # 和tft共享宿主机网络

此时脚本连接参数改为宿主机地址127.0.0.1,端口使用5432(host模式下PostgreSQL直接绑定宿主机5432端口):

conn, cur = create_connection(
    host="127.0.0.1", 
    dbname="postgres",  # 默认数据库名
    user="postgres",  # 默认用户名
    password="*********"
)

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.18 10:20:24