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只是声明要暴露的端口,实际服务没监听的话毫无意义。
修正方法:
- 将Django的数据库连接配置中的端口从54320改为5432。
- (可选但更规范)删除
db服务里的expose: 54320配置。
额外提醒:depends_on仅保证db容器先启动,不代表Postgres服务已经初始化完成并接受连接。如果Django启动时Postgres还没就绪,也会出现连接失败。可以在Django的启动命令前添加等待脚本(比如wait-for-it db:5432 -- python manage.py runserver...),确保Postgres服务可用后再启动Django。
内容的提问来源于stack exchange,提问作者AlxVallejo
相关产品推荐
相关产品推荐

