Docker部署Django连接PostgreSQL偶发连接拒绝问题求助
问题:Django容器偶发无法连接PostgreSQL容器
我先运行PostgreSQL容器,再启动Python(Django)容器,连接数据库时偶发报错。删除Compose项目重新创建时,50%概率出现该错误;单独重启backend容器后恢复正常。这是我第一次用Docker,求帮助和建议。
报错信息
django.db.utils.OperationalError: could not connect to server: Connection refused Is the server running on host "postgres" (192.168.128.2) and accepting TCP/IP connections on port 5432?
相关配置
settings.py 数据库配置
'default': { 'ENGINE': 'django.db.backends.postgresql_psycopg2', 'NAME': "postgres", 'USER': "postgres", 'PASSWORD': "postgres", 'HOST': "postgres", 'PORT': "5432", }
docker-compose.yml 配置
version: "3.8" services: postgres: image: postgres:15-alpine restart: always environment: POSTGRES_USER: postgres POSTGRES_DB: postgres POSTGRES_PASSWORD: postgres volumes: - ./postgres-data:/var/lib/postgresql/ ports: - "5432:5432" adminer: image: adminer restart: always links: - postgres ports: - "8080:8080" backend: links: - postgres - adminer build: ./settings/ command: python manage.py runserver 0.0.0.0:8000 ports: - "8000:8000"
Dockerfile 配置
FROM python:3.8.16-buster WORKDIR /settings COPY . . RUN pip install -r requirements.txt
原因分析
Docker Compose默认会同时启动所有容器,即使配置了links,PostgreSQL容器启动后仍需要时间完成数据库初始化(比如创建默认数据库、用户),此时Django容器已开始尝试连接,就会出现连接被拒绝的错误。重启backend容器时,PostgreSQL已经初始化完成,因此能正常连接。
解决方法
方法1:用健康检查确保PostgreSQL就绪后再启动Django
修改docker-compose.yml,给postgres服务添加健康检查,让backend服务等待postgres完全就绪后再启动:
更新postgres服务配置
postgres: image: postgres:15-alpine restart: always environment: POSTGRES_USER: postgres POSTGRES_DB: postgres POSTGRES_PASSWORD: postgres volumes: - ./postgres-data:/var/lib/postgresql/ ports: - "5432:5432" healthcheck: test: ["CMD-SHELL", "pg_isready -U postgres"] interval: 5s timeout: 5s retries: 5
更新backend服务配置(替换原links和添加depends_on)
backend: depends_on: postgres: condition: service_healthy adminer: condition: service_started build: ./settings/ command: python manage.py runserver 0.0.0.0:8000 ports: - "8000:8000"
注:Compose v3中
links已被depends_on替代,建议移除links,Compose会自动创建默认网络,服务名可直接作为主机名访问。
方法2:给Django添加启动前等待脚本
在backend容器启动前,先检查PostgreSQL是否可连接,再启动Django服务:
修改Dockerfile(安装postgresql-client工具)
FROM python:3.8.16-buster WORKDIR /settings # 安装pg_isready工具 RUN apt-get update && apt-get install -y postgresql-client && rm -rf /var/lib/apt/lists/* COPY . . RUN pip install -r requirements.txt
修改backend服务的command
backend: depends_on: - postgres - adminer build: ./settings/ command: > sh -c " until pg_isready -h postgres -p 5432 -U postgres; do echo '等待PostgreSQL就绪...' sleep 2 done python manage.py runserver 0.0.0.0:8000 " ports: - "8000:8000"
额外建议
- 避免使用
links,Compose默认创建的网络已支持服务名解析,depends_on更适合管理服务依赖 - 检查
./postgres-data目录的权限,确保PostgreSQL容器有读写权限,避免初始化失败 - 可通过
docker-compose logs postgres查看PostgreSQL容器日志,确认初始化完成的时间节点
内容的提问来源于stack exchange,提问作者Awely17
相关产品推荐
相关产品推荐

