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

Docker部署Django+PostgreSQL后localhost无法访问问题求助

Django + PostgreSQL容器化后连接超时问题排查与解决

问题背景

系统:Ubuntu 22.04.1 LTS
按照《Django for Professionals》步骤操作,使用SQLite时Django项目正常运行;容器化Django+PostgreSQL后,访问127.0.0.1:8000提示无法连接,等待后查看日志出现如下错误:

psycopg2.OperationalError: connection to server at "db" (172.21.0.2), port 5432 failed: Connection timed out
web_1 | Is the server running on that host and accepting TCP/IP connections?

当前配置文件如下:

Dockerfile

# Pull base image
FROM python:3.10.6-slim-bullseye
# Set environment variables
ENV PIP_DISABLE_PIP_VERSION_CHECK 1
ENV PYTHONDONTWRITEBYTECODE 1
ENV PYTHONUNBUFFERED 1
# Set work directory
WORKDIR /code
# Install dependencies
COPY ./requirements.txt .
RUN pip install -r requirements.txt
# Copy project
COPY . .

docker-compose.yml

version: "3.9"

services:
 web:
  build: .
  command: python /code/manage.py runserver 0.0.0.0:8000
  volumes:
   - .:/code
  ports:
   - 8000:8000
  depends_on:
   - db
 db:
  image: postgres:13
  volumes:
   - postgres_data:/var/lib/postgresql/data/
  environment:
   - "POSTGRES_HOST_AUTH_METHOD=trust"

volumes:
 postgres_data:

settings.py数据库配置

DATABASES = {
    "default": {
        "ENGINE": "django.db.backends.postgresql",
        "NAME": "postgres",
        "USER": "postgres",
        "PASSWORD": "postgres",
        "HOST": "db",  # set in docker-compose.yml
        "PORT": 5432,  # default postgres port
    }
}

解决方案

1. 统一数据库认证配置

settings.py中设置了密码postgres,但PostgreSQL容器未配置对应环境变量,同时启用POSTGRES_HOST_AUTH_METHOD=trust会导致认证逻辑冲突。修改docker-compose.yml的db服务,明确配置与settings匹配的数据库参数:

db:
  image: postgres:13
  volumes:
   - postgres_data:/var/lib/postgresql/data/
  environment:
   - POSTGRES_DB=postgres
   - POSTGRES_USER=postgres
   - POSTGRES_PASSWORD=postgres
   # 移除POSTGRES_HOST_AUTH_METHOD=trust,使用密码认证更安全

2. 解决PostgreSQL未就绪就启动Django的问题

depends_on仅保证容器启动顺序,不保证PostgreSQL服务完全就绪(如初始化完成、可接受连接),可通过以下方式处理:

方式A:添加健康检查

给db服务添加健康检查,让web服务等db就绪后再启动:

db:
  image: postgres:13
  volumes:
   - postgres_data:/var/lib/postgresql/data/
  environment:
   - POSTGRES_DB=postgres
   - POSTGRES_USER=postgres
   - POSTGRES_PASSWORD=postgres
  healthcheck:
    test: ["CMD-SHELL", "pg_isready -U postgres"]
    interval: 5s
    timeout: 5s
    retries: 5

web:
  build: .
  command: python /code/manage.py runserver 0.0.0.0:8000
  volumes:
   - .:/code
  ports:
   - 8000:8000
  depends_on:
   db:
     condition: service_healthy

方式B:添加启动等待脚本

在Dockerfile中安装wait-for-it工具,让web服务等待PostgreSQL端口就绪:

# 安装wait-for-it
RUN apt-get update && apt-get install -y wait-for-it

修改web服务启动命令:

web:
  build: .
  command: wait-for-it db:5432 -- python /code/manage.py runserver 0.0.0.0:8000
  volumes:
   - .:/code
  ports:
   - 8000:8000
  depends_on:
   - db

3. 确保使用兼容的PostgreSQL驱动

slim版Python镜像缺少编译psycopg2的依赖,建议使用预编译的psycopg2-binary。检查requirements.txt:

# 其他依赖...
psycopg2-binary>=2.9.0
django>=4.0  # 匹配书籍使用的版本

重新构建镜像:

docker-compose build --no-cache

4. 验证容器间网络连通性

若以上步骤无效,进入web容器测试与db的连通性:

# 进入web容器
docker-compose exec web bash

# 测试ping db容器
ping db

# 测试端口连通性
telnet db 5432

若ping不通,检查Docker网络配置;若telnet不通,确认Postgres服务是否正常启动。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.09 21:45:29