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

在PostgreSQL Docker容器中运行SQLAlchemy遇连接拒绝问题

Postgres容器内Python连接数据库失败:Connection refused

问题详情

Dockerfile代码

FROM postgres

RUN apt-get update && \
    apt-get install \
    --yes \
    --no-install-recommends \
    python3-pip libpq-dev

RUN pip3 install \
    --default-timeout=100 \
    sqlalchemy sqlalchemy-utils psycopg2-binary 

COPY database.py .

CMD python3 database.py

database.py代码

from sqlalchemy import create_engine
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.orm import sessionmaker
from sqlalchemy_utils import database_exists, create_database

SQLALCHEMY_DATABASE_URL = (
    "postgresql+psycopg2://postgres:password@localhost/mydb"
)
# SQLALCHEMY_DATABASE_URL = "postgresql:///mydb"

engine = create_engine(SQLALCHEMY_DATABASE_URL)
if not database_exists(engine.url):
    print("Database did not exit. Creating it.")
    create_database(engine.url)

SessionLocal = sessionmaker(autocommit=False, autoflush=False, bind=engine)

Base = declarative_base()

容器运行命令

docker run --name <SOME_NAME> -p 5432:5432 -e POSTGRES_PASSWORD=password -d <BUILD_TAG>

报错信息

sqlalchemy.exc.OperationalError: (psycopg2.OperationalError) 连接服务器 "localhost" (127.0.0.1) 端口5432失败:Connection refused
服务器是否在该主机上运行并接受TCP/IP连接?
连接服务器 "localhost" (::1) 端口5432失败:Cannot assign requested address
服务器是否在该主机上运行并接受TCP/IP连接?

已尝试切换端口(如5433)、移除-p 5432:5432参数,问题依旧,推测容器内部无法访问5432端口。


问题根源

  1. Postgres服务未启动:你用CMD python3 database.py覆盖了Postgres官方镜像默认的启动命令,容器启动后直接运行Python脚本,根本没启动Postgres服务。
  2. localhost指向问题:容器内的localhost是容器自身,即使Postgres服务启动,若未就绪就执行连接,也会触发拒绝错误。

解决方案

方案1:修复启动逻辑,先启动Postgres再执行脚本

  1. 创建启动脚本entrypoint.sh:
#!/bin/bash
# 启动Postgres服务
docker-entrypoint.sh postgres &

# 等待Postgres就绪
until pg_isready -U postgres; do
  echo "等待Postgres服务启动..."
  sleep 2
done

# 执行Python脚本
python3 database.py
  1. 给脚本添加执行权限:chmod +x entrypoint.sh
  2. 修改Dockerfile,替换CMD为ENTRYPOINT:
FROM postgres

RUN apt-get update && \
    apt-get install \
    --yes \
    --no-install-recommends \
    python3-pip libpq-dev

RUN pip3 install \
    --default-timeout=100 \
    sqlalchemy sqlalchemy-utils psycopg2-binary 

COPY database.py .
COPY entrypoint.sh .

ENTRYPOINT ["./entrypoint.sh"]

方案2:调整数据库连接字符串(配合方案1使用)

用Unix套接字连接Postgres,修改database.py中的连接地址:

SQLALCHEMY_DATABASE_URL = "postgresql+psycopg2://postgres:password@/mydb?host=/var/run/postgresql"

或者简化为:

SQLALCHEMY_DATABASE_URL = "postgresql:///mydb"

方案3:拆分容器(最佳实践)

将Postgres和Python应用拆分为两个独立容器,用Docker Compose管理:

  1. 创建docker-compose.yml:
version: '3.8'
services:
  db:
    image: postgres
    environment:
      POSTGRES_PASSWORD: password
      POSTGRES_DB: mydb
    volumes:
      - postgres_data:/var/lib/postgresql/data/
  app:
    build: .
    depends_on:
      - db
    environment:
      DATABASE_URL: "postgresql+psycopg2://postgres:password@db/mydb"
volumes:
  postgres_data:
  1. 修改database.py读取环境变量:
import os
from sqlalchemy import create_engine
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.orm import sessionmaker
from sqlalchemy_utils import database_exists, create_database

SQLALCHEMY_DATABASE_URL = os.getenv("DATABASE_URL", "postgresql+psycopg2://postgres:password@db/mydb")

engine = create_engine(SQLALCHEMY_DATABASE_URL)
if not database_exists(engine.url):
    print("数据库不存在,正在创建...")
    create_database(engine.url)

SessionLocal = sessionmaker(autocommit=False, autoflush=False, bind=engine)

Base = declarative_base()
  1. 启动容器:docker-compose up --build -d

内容的提问来源于stack exchange,提问作者J Agustin Barrachina

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.28 12:25:22