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

Docker容器环境下Django无法连接PostgreSQL导致启动失败

故障根因
  • docker-compose.yml中配置的depends_on仅控制容器启动顺序,不会等待PostgreSQL服务完全就绪就启动Django容器。PostgreSQL容器启动后需要经过崩溃恢复、实例初始化流程(从日志可见上次数据库是被强制快速关闭,本次启动需要执行事务回滚等恢复操作),这一阶段虽然容器已处于running状态、5432端口已开始监听,但服务还无法处理正常连接请求,Django此时发起连接就会收到the database system is starting up的报错。
  • 现有Django启动脚本没有配置数据库连接重试逻辑,也未设置连接超时阈值,碰到数据库未就绪的情况时,psycopg2驱动的连接逻辑会持续阻塞等待,最终表现为打印完系统检查结果后卡住无响应。
  • 额外隐患:PostgreSQL日志中出现了initdb相关输出,正常情况下如果持久化目录存在完整的数据库数据,容器启动时不会执行初始化流程,该现象说明当前挂载的postgresql_data持久化卷可能存在权限异常、数据损坏问题。
修复方案

1. 调整Docker Compose依赖规则,增加服务健康检查

替换原有普通depends_on配置,通过健康检查机制确保PostgreSQL服务真正可用后再启动Django,修改docker-compose.yml内容如下:

version: "3.7"

services:
  postgresql:
    container_name: postgresql
    image: postgres:14.3-bullseye
    restart: always
    volumes:
      - postgresql_data:/var/lib/postgresql/data
    environment:
      - POSTGRES_DB=postgres
      - POSTGRES_USER=postgres
      - POSTGRES_PASSWORD=12345678
    # 新增PostgreSQL健康检查
    healthcheck:
      test: ["CMD-SHELL", "pg_isready -U postgres"]
      interval: 2s
      timeout: 2s
      retries: 30

  django:
    container_name: django
    build: .
    volumes:
      - static_volume:/app/static
    depends_on:
      # 等待PostgreSQL健康检查通过后再启动
      postgresql:
        condition: service_healthy

  nginx:
    container_name: nginx
    build: ./nginx/.
    volumes:
      - static_volume:/app/static
    ports:
      - "80:80"
      - "443:443"
    depends_on:
      - django

volumes:
  static_volume:
  postgresql_data:

2. 优化Django启动脚本,增加重试和异常退出逻辑

修改django-enterypoint.sh,开启脚本错误自动退出,同时增加数据库连接重试逻辑,避免数据库未就绪时流程阻塞:

# 任意命令执行失败时直接退出脚本,避免异常流程继续执行
set -e

# 循环重试数据库迁移,直到数据库就绪连接成功
until python manage.py migrate --no-input
do
  echo "数据库服务未就绪,2秒后重试..."
  sleep 2
done

python manage.py collectstatic --no-input
python manage.py runserver 0.0.0.0:8000

# gunicorn wall.wsgi:application --bind 0.0.0.0:8000

3. 持久化卷异常排查(上述操作无效时执行)

如果调整启动逻辑后仍反复出现initdb初始化提示,说明持久化卷数据已损坏,可先备份卷内重要数据后,清理损坏卷重新初始化(注意:该操作会清空原有数据库数据,必须确认备份完成后再执行):

# 停止所有运行中的容器
docker compose down
# 删除损坏的数据库持久化卷,将<项目目录名>替换为实际的项目文件夹名称
docker volume rm <项目目录名>_postgresql_data
# 重新构建启动服务
docker compose up -d --build
快速验证方法

如果暂时不想修改配置验证问题,可在启动PostgreSQL容器后手动等待10~15秒,给数据库留足恢复启动时间,再启动Django容器即可正常连接。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.30 21:45:38