Docker Compose部署后端+Postgres:Python无法连接数据库问题
PostgreSQL连接问题排查与解决方案(Docker Compose + SQLAlchemy)
问题背景
用户提供的Docker Compose配置:
services: server: build: context: . ports: - 8000:8000 depends_on: db: condition: service_healthy db: image: postgres:latest restart: always user: postgres secrets: - db-password volumes: - db-data:/var/lib/postgresql/data # copy the sql script to create tables - ./create_tables.sql:/docker-entrypoint-initdb.d/create_tables.sql environment: - POSTGRES_DB=volunteer_api_db - POSTGRES_PASSWORD_FILE=/run/secrets/db-password expose: - 5432 healthcheck: test: [ "CMD", "pg_isready" ] interval: 10s timeout: 5s retries: 5 volumes: db-data: secrets: db-password: file: db/password.txt
SQLAlchemy报错信息:
api-server-1 | sqlalchemy.exc.OperationalError: (psycopg2.OperationalError) connection to server at "localhost" (127.0.0.1), port 5432 failed: Connection refused api-server-1 | Is the server running on that host and accepting TCP/IP connections? api-server-1 | connection to server at "localhost" (::1), port 5432 failed: Cannot assign requested address api-server-1 | Is the server running on that host and accepting TCP/IP connections? api-server-1 | api-server-1 | (Background on this error at: https://sqlalche.me/e/20/e3q8) api-server-1 | api-server-1 exited with code 1
当前使用的连接字符串:
SQLALCHEMY_DATABASE_URL = "postgresql://postgres:postgres@localhost/volunteer_api_db"
核心问题分析
容器内的localhost指向容器自身,而非PostgreSQL容器。Docker Compose会自动创建一个用户定义网络,同一网络内的服务可以通过服务名称(即Compose配置里的db)作为主机名互相访问,这是容器间通信的标准方式。
修复步骤
- 修正连接字符串:将主机名从
localhost改为db,同时确保密码与db/password.txt文件中的内容完全一致:# 替换your_secure_password为db/password.txt中的实际密码 SQLALCHEMY_DATABASE_URL = "postgresql://postgres:your_secure_password@db/volunteer_api_db" - 无需额外网络/links配置:Compose默认生成的网络已经允许
server服务通过db主机名访问PostgreSQL容器,expose配置已开放5432端口供内部通信,不需要额外映射端口到宿主机(除非你需要从宿主机直接连接数据库)。 - 验证密码一致性:连接字符串中的密码必须和
db/password.txt内的内容匹配——PostgreSQL容器通过POSTGRES_PASSWORD_FILE读取该文件设置密码,不匹配会导致认证失败。
关于Docker Secrets的疑问
- Docker Secrets的作用是安全传递敏感数据(比如数据库密码)到容器内,避免在Compose文件或代码中硬编码明文密码。
- 连接字符串里的密码是SQLAlchemy向PostgreSQL认证的凭证,它必须和Secrets文件中存储的密码一致——Secrets只是传递密码的安全方式,最终程序连接数据库还是需要使用正确的密码凭证。
内容的提问来源于stack exchange,提问作者James Young
相关产品推荐
相关产品推荐

