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网络内使用服务名访问,后者在宿主机直接访问映射的端口。解决步骤:
- 修改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") ) - 修正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 - 修正RabbitMQ连接地址:
同样,容器内访问RabbitMQ需使用服务名rabbitmq而非localhost:con_pika = pika.BlockingConnection(pika.ConnectionParameters("rabbitmq", 5672, "/", pika.PlainCredentials("user", "111"))) - 重新构建并启动服务:
执行以下命令更新容器:docker-compose down docker-compose up --build python-service
- 修改Python代码,读取环境变量配置:
内容的提问来源于stack exchange,提问作者Vlad
相关产品推荐
相关产品推荐

