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

Docker Compose环境下Django无法连接PostgreSQL数据库

问题描述

我知道这个问题已有相关提问,通常错误是未将DB_HOST设置为Docker服务名,但我已经把它设为db了。以下是我的docker-compose.yml配置:

version: "3"

services:
  db:
    image: postgres:latest
    restart: always
    ports:
      - "54320:5432"
    expose:
      - "54320"
    volumes:
      - ./database-data:/var/lib/postgresql/data/ # persist data even if container shuts down
    environment:
      - POSTGRES_DB=postgres
      - POSTGRES_USER=postgres
      - POSTGRES_PASSWORD=postgres
      # POSTGRES_HOST_AUTH_METHOD: trust
  django:
    build: ./api
    restart: always
    command: ["python", "manage.py", "runserver", "0.0.0.0:8000"]
    volumes:
      - ./api:/app/api
    ports:
      - "8000:8000"
    depends_on:
      - db
  raddl_admin:
    build: ./frontend/raddl_admin
    stdin_open: true # docker run -i
    tty: true # docker run -t
    command: ["npm", "start"]
    ports:
      - "3000:3000"
    volumes:
      - ./frontend/raddl_admin:/app/frontend/raddl_admin
      - /app/frontend/raddl_admin/node_modules

volumes:
  database-data: # named volumes can be managed easier using docker-compose

Django服务日志显示:

django.db.utils.OperationalError: could not connect to server: Connection refused
Is the server running on host "db" (172.18.0.2) and accepting
TCP/IP connections on port 54320?

可见Django尝试连接db的54320端口,且相关环境变量已配置。我甚至能从Django服务ping通db服务:

docker exec -it 1f764333ace2 bash | ping db
PING db (23.221.222.250): 56 data bytes
64 bytes from 23.221.222.250: icmp_seq=0 ttl=50 time=42.055 ms
64 bytes from 23.221.222.250: icmp_seq=1 ttl=50 time=42.382 ms

请问为何无法从Django连接到db服务?

解决方案

问题出在端口配置的误解上:

  • Docker Compose网络内的容器通信,用的是容器内部的服务端口,不是映射到主机的端口。Postgres容器内部默认监听5432端口,你配置的ports: "54320:5432"只是把主机的54320端口转发到容器的5432端口,这对容器间通信无效。
  • 你给db服务加的expose: 54320完全多余,因为Postgres根本没在容器内部监听这个端口,expose只是声明要暴露的端口,实际服务没监听的话毫无意义。

修正方法:

  1. 将Django的数据库连接配置中的端口从54320改为5432。
  2. (可选但更规范)删除db服务里的expose: 54320配置。

额外提醒:depends_on仅保证db容器先启动,不代表Postgres服务已经初始化完成并接受连接。如果Django启动时Postgres还没就绪,也会出现连接失败。可以在Django的启动命令前添加等待脚本(比如wait-for-it db:5432 -- python manage.py runserver...),确保Postgres服务可用后再启动Django。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.10 14:25:15