Docker容器网络问题:后端无法连接PostgreSQL数据库
问题场景
部署了三个Docker容器:React前端、FastAPI后端、PostgreSQL数据库,通过docker network connect将所有容器接入同一网络。前端可正常与后端通信,本地机器也能访问所有容器,但后端容器无法连接PostgreSQL,报错如下:
error establishing DB connection: (psycopg2.OperationalError) could not connect to server: Connection refused
Is the server running on host "0.0.0.0" and accepting
TCP/IP connections on port 5432?
本地直接执行python database.py可正常连接数据库,代码示例:
if __name__ == "__main__": d = Database("0.0.0.0", 5432, "postgres", "password") d.conn_execute("")
后端数据库类代码片段:
class Database(): def __init__(self, host, port, user, password) -> None: self.host = host self.port = port self.user = user self.password = password def conn_execute(self, query) -> None: try: print(f"postgresql://{self.user}:{self.password}@{self.host}:{self.port}") self.engine = create_engine(f"postgresql://{self.user}:{self.password}@{self.host}:{self.port}") with self.engine.connect() as connection: result = connection.execute(query) for i in result: print(i) except Exception as e: print(f"error establishing DB connection: {e}")
尝试过Docker Compose、更换端口、使用localhost和0.0.0.0均无效,更换为MongoDB后可正常工作,怀疑是PostgreSQL相关配置问题。
排查与解决步骤
1. 修正数据库连接的Host地址
Docker容器间通信时,不能用0.0.0.0或localhost,必须使用PostgreSQL容器的容器名称(更稳定)或容器IP:
- 查看PostgreSQL容器名称:执行
docker ps找到容器的NAMES字段,例如postgres-db - 修改后端数据库连接的host参数为容器名称,示例:
d = Database("postgres-db", 5432, "postgres", "password")
2. 检查PostgreSQL的TCP/IP访问配置
PostgreSQL默认可能仅允许本地连接,需修改配置开放外部访问:
- 进入PostgreSQL容器:
docker exec -it <postgres容器名> bash - 编辑
/var/lib/postgresql/data/postgresql.conf,修改:listen_addresses = '*' - 编辑
/var/lib/postgresql/data/pg_hba.conf,添加允许同一Docker网络的IP段访问(以默认子网172.17.0.0/16为例):host all all 172.17.0.0/16 scram-sha-256 - 重启PostgreSQL容器:
docker restart <postgres容器名>
3. 确认PostgreSQL容器的环境变量与端口
启动PostgreSQL容器时,需确保设置正确的环境变量:
docker run -d \ --name postgres-db \ --network <你的Docker网络名> \ -e POSTGRES_USER=postgres \ -e POSTGRES_PASSWORD=password \ -e POSTGRES_DB=<你的数据库名> \ postgres:latest
注意:若后端连接未指定数据库名,需确保POSTGRES_DB已创建,或在连接URL中补充数据库名(格式:postgresql://user:pass@host:port/dbname)
4. 验证Docker网络连通性
- 在后端容器内ping PostgreSQL容器名称,确认解析正常:
docker exec -it <后端容器名> ping postgres-db - 检查两个容器是否在同一网络:
docker network inspect <网络名>,查看Containers列表是否包含两者
内容的提问来源于stack exchange,提问作者AI Humanizer

