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

