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

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)作为主机名互相访问,这是容器间通信的标准方式。

修复步骤

  1. 修正连接字符串:将主机名从localhost改为db,同时确保密码与db/password.txt文件中的内容完全一致:
    # 替换your_secure_password为db/password.txt中的实际密码
    SQLALCHEMY_DATABASE_URL = "postgresql://postgres:your_secure_password@db/volunteer_api_db"
    
  2. 无需额外网络/links配置:Compose默认生成的网络已经允许server服务通过db主机名访问PostgreSQL容器,expose配置已开放5432端口供内部通信,不需要额外映射端口到宿主机(除非你需要从宿主机直接连接数据库)。
  3. 验证密码一致性:连接字符串中的密码必须和db/password.txt内的内容匹配——PostgreSQL容器通过POSTGRES_PASSWORD_FILE读取该文件设置密码,不匹配会导致认证失败。

关于Docker Secrets的疑问

  • Docker Secrets的作用是安全传递敏感数据(比如数据库密码)到容器内,避免在Compose文件或代码中硬编码明文密码。
  • 连接字符串里的密码是SQLAlchemy向PostgreSQL认证的凭证,它必须和Secrets文件中存储的密码一致——Secrets只是传递密码的安全方式,最终程序连接数据库还是需要使用正确的密码凭证。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.13 09:05:23