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

Python无法连接Docker容器中PostgreSQL的问题求助

PostgreSQL Docker容器连接问题:Python psycopg2无法连接,但Java和pgAdmin正常

PostgreSQL运行在Docker容器中,Java服务和pgAdmin均可正常建立连接,但Python通过psycopg2连接时失败,报错连接被拒绝。以下是相关代码、配置及报错信息:

Python服务代码

import pika
import psycopg2
import json
import sys
import signal


queues = ["create", "update", "remove", "status"]
con_db = None


def create_tables():
    cursor = con_db.cursor()
    try:
        cursor.execute("""CREATE TABLE IF NOT EXISTS cook (cook_id INTEGER PRIMARY KEY NOT NULL, first_name VARCHAR(128) NOT NULL, last_name VARCHAR(128) NOT NULL);""")
        cursor.execute("""CREATE TABLE IF NOT EXISTS recipe (recipe_id INTEGER PRIMARY KEY NOT NULL, title VARCHAR(255) NOT NULL, descripion TEXT NOT NULL, fk_cook_id INTEGER REFERENCES cook(cook_id) NOT NULL);""")
    except psycopg2.Error as e:
        print(f"ERROR unable to create tables: {e.pgerror}")
    finally:
        cursor.close()


def on_message(ch, method, properties, body):
    print(f"Сообщение - {body}; получено с канала - {method.routing_key}")


if __name__ == "__main__":
    con_db = psycopg2.connect(
        dbname="db",
        user="admin",
        password="admin1234",
        host="localhost",
        port="6544"
    )

    print("Start app....")

    con_pika = pika.BlockingConnection(pika.ConnectionParameters("localhost", 5672, "/", pika.PlainCredentials("user", "111")))
    channel = con_pika.channel()

    channel.queue_declare(queues[0])
    channel.queue_declare(queues[1])
    channel.queue_declare(queues[2])

    channel.basic_consume(queue=queues[0], on_message_callback=on_message, auto_ack=True)
    channel.basic_consume(queue=queues[1], on_message_callback=on_message, auto_ack=True)
    channel.basic_consume(queue=queues[2], on_message_callback=on_message, auto_ack=True)

    create_tables()


    def signal_handler(sig, frame):
        print("Завершение работы...")
        channel.close()
        con_pika.close()
        sys.exit(0)

    signal.signal(signal.SIGINT, signal_handler)

    channel.start_consuming()

Docker-Compose配置

version: '3'
services:
  java-service:
    build:
      context: ./java-spring-service
      dockerfile: Dockerfile
    ports:
      - "8081:8081"
    depends_on:
      - postgres
    networks:
      - my-network
  python-service:
    build:
      context: ./python-translate-api
      dockerfile: Dockerfile
    ports:
      - "5000:5000"
    depends_on:
      postgres:
          condition: service_completed_successfully
    environment:
      DB_HOST: postgres
      DB_PORT: 6544
      DB_NAME: db
      DB_USER: admin
      DB_PASSWORD: admin1234

  postgres:
    image: postgres:latest
    environment:
      POSTGRES_USER: admin
      POSTGRES_PASSWORD: admin1234
      POSTGRES_DB: db
    ports:
      - "6544:5432"
    networks:
      - my-network
    hostname: postgres


  flyway:
    image: flyway/flyway
    volumes:
      - ./data/postgres/src/main/resources/db/migration:/flyway/sql
    depends_on:
      - postgres
    environment:
      - FLYWAY_URL=jdbc:postgresql://postgres:5432/db
      - FLYWAY_USER=admin
      - FLYWAY_PASSWORD=admin1234
    command: [ "migrate" ]
    networks:
      - my-network


  rabbitmq:
    image: rabbitmq:management
    environment:
      RABBITMQ_DEFAULT_USER: user
      RABBITMQ_DEFAULT_PASS: 111
    restart: no
    ports:
      - "5672:5672"
      - "15672:15672"
    networks:
      - my-network
  redis:
    image: "redis:latest"
    ports:
      - "6379:6379"
    networks:
      - my-network

networks:
  my-network:
    driver: bridge

Python服务Dockerfile

FROM python:3.12

WORKDIR /app

COPY requirements.txt ./

RUN pip install -r requirements.txt

COPY . .

CMD ["python", "./app.py"]

报错信息

File "/app/./app.py", line 36, in <module>
    psycopg2.connect('postgres://postgres:postgres@localhost:6544/db')
  File "/usr/local/lib/python3.12/site-packages/psycopg2/__init__.py", line 122, in connect
    conn = _connect(dsn, connection_factory=connection_factory, **kwasync)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
psycopg2.OperationalError: 连接到"localhost"(127.0.0.1)的6544端口失败:连接被拒绝
        服务器是否在该主机运行并接受TCP/IP连接?
连接到"localhost"(::1)的6544端口失败:无法分配请求的地址
        服务器是否在该主机运行并接受TCP/IP连接?

问题原因及解决方法

  • 核心原因:Python服务运行在Docker容器内,代码硬编码localhost作为数据库和RabbitMQ的主机地址,但容器内的localhost指向容器自身,而非PostgreSQL或RabbitMQ容器。Java服务和pgAdmin能正常连接是因为前者在Docker网络内使用服务名访问,后者在宿主机直接访问映射的端口。

  • 解决步骤:

    1. 修改Python代码,读取环境变量配置:
      替换硬编码的数据库连接参数,使用Docker-Compose中定义的环境变量:
      import os
      # ... 其他代码保持不变
      if __name__ == "__main__":
          con_db = psycopg2.connect(
              dbname=os.getenv("DB_NAME"),
              user=os.getenv("DB_USER"),
              password=os.getenv("DB_PASSWORD"),
              host=os.getenv("DB_HOST"),
              port=os.getenv("DB_PORT")
          )
      
    2. 修正Docker-Compose中的数据库端口配置:
      Docker网络内访问PostgreSQL应使用容器内部端口5432,而非宿主机映射的6544,修改python-service的环境变量:
      python-service:
        # ... 其他配置不变
        environment:
          DB_HOST: postgres
          DB_PORT: 5432
          DB_NAME: db
          DB_USER: admin
          DB_PASSWORD: admin1234
      
    3. 修正RabbitMQ连接地址:
      同样,容器内访问RabbitMQ需使用服务名rabbitmq而非localhost:
      con_pika = pika.BlockingConnection(pika.ConnectionParameters("rabbitmq", 5672, "/", pika.PlainCredentials("user", "111")))
      
    4. 重新构建并启动服务:
      执行以下命令更新容器:
      docker-compose down
      docker-compose up --build python-service
      

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.29 13:25:54