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
相关产品推荐
相关产品推荐

