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

Docker化Django项目连接PostgreSQL报错:无法连接localhost:5432

Django Docker化连接PostgreSQL失败问题排查

问题背景

尝试将Django项目Docker化,配置文件及错误信息如下:

Dockerfile

FROM python:3.9-bullseye

WORKDIR /app

ENV PYTHONUNBUFFERED=1

COPY csgo .

RUN apt-get update -y \
    && apt-get upgrade -y pip \
    && pip install --upgrade pip \
    && pip install -r requirements.txt

CMD ["python", "manage.py", "runserver", "127.0.0.1:8000"]

docker-compose.yml

version: '3'

services:
  web:
    build:
      context: .
      dockerfile: Dockerfile
    env_file:
      - csgo.env
    volumes:
      - .:/code
    ports:
      - 8000:8000
    depends_on:
      - db

  db:
    image: postgres:13
    restart: always
    ports:
      - 5432:5432
    env_file:
      - csgo.env
    environment:
      - POSTGRES_PASSWORD=postgres
      - DB_NAME=postgres
      - DB_USER=postgres
      - DB_PASSWORD=postgres
      - DB_HOST=localhost
    volumes:
      - ./db/psql-init/db.sql:/docker-entrypoint-initdb.d/db.sql
      - postgres_data:/var/lib/postgresql/data/

volumes:
  postgres_data:

执行docker-compose up时的错误日志

django.db.utils.OperationalError: could not connect to server: Connection refused
csgo-web-1    |         Is the server running on host "localhost" (127.0.0.1) and accepting
csgo-web-1    |         TCP/IP connections on port 5432?
csgo-web-1    | could not connect to server: Cannot assign requested address
csgo-web-1    |         Is the server running on host "localhost" (::1) and accepting
csgo-web-1    |         TCP/IP connections on port 5432?

当前端口占用情况

com.docke 14554 user  149u  IPv6 0xd0180dc2abc35a25      0t0    TCP *:5432 (LISTEN)

问题分析与解决

1. 错误信息中“Is the server running on host "localhost"”的含义

这条错误是Django连接PostgreSQL失败后的提示,直白来说就是:Django当前配置的数据库主机是localhost,但它在这个地址的5432端口找不到运行的PostgreSQL服务。

在Docker环境里,每个容器的localhost是独立的——web容器的localhost指向它自己的内部网络空间,而非宿主机或其他容器。所以当Django在web容器内尝试连接localhost:5432时,实际是在找自身容器内的PostgreSQL,而你的PostgreSQL运行在单独的db容器中,自然会连接失败。

2. 无法连接端口5432的核心原因

  • 容器网络隔离:Docker Compose会为每个服务创建独立容器,默认同属一个自定义网络。web和db是两个独立网络节点,不能通过各自的localhost互相访问。
  • 配置错误:你在docker-compose.yml的db服务中设置了DB_HOST=localhost,这个环境变量会传递给Django,导致它错误地尝试连接自身容器内的数据库,而非db容器。

3. 修复步骤

步骤1:修正数据库主机配置

将docker-compose.yml中db服务的DB_HOST=localhost改为DB_HOST=db——Docker Compose会自动为服务创建DNS解析,db这个服务名可以直接映射到对应容器的IP:

db:
  image: postgres:13
  restart: always
  ports:
    - 5432:5432
  env_file:
    - csgo.env
  environment:
    - POSTGRES_PASSWORD=postgres
    - DB_NAME=postgres
    - DB_USER=postgres
    - DB_PASSWORD=postgres
    - DB_HOST=db  # 此处修改为db
  volumes:
    - ./db/psql-init/db.sql:/docker-entrypoint-initdb.d/db.sql
    - postgres_data:/var/lib/postgresql/data/

步骤2:调整Django服务的监听地址

当前Dockerfile中runserver绑定了127.0.0.1:8000,这会导致仅容器内部可访问,外部(包括宿主机)无法通过端口映射访问。需改为0.0.0.0:8000:

CMD ["python", "manage.py", "runserver", "0.0.0.0:8000"]

步骤3:确保环境变量配置一致

检查csgo.env文件,确保其中的DB_HOST值同样为db,避免和docker-compose.yml的配置冲突。

步骤4:清理旧容器并重新构建

执行以下命令彻底清理旧容器,再重新启动服务:

docker-compose down
docker-compose up --build

额外说明

你看到的端口占用信息显示*:5432被Docker进程监听,这是db容器映射到宿主机的端口,但web容器无需通过宿主机端口连接db容器,直接通过容器间网络用服务名访问即可。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.19 16:55:24