Docker部署Django对接PostgreSQL报5432端口连接拒绝错误求助
Docker部署Postgres时5432端口连接报错排查
典型报错信息
Is the server running on host "localhost" (::1) and accepting TCP/IP connections on port 5432?
排查修正方向
- 移除db服务中无效的
POSTGRES_HOST环境变量
这是当前场景下最高概率的问题:Postgres官方镜像本身并不识别POSTGRES_HOST这个配置项,设置它完全不会改变数据库的监听行为。但绝大多数基于Postgres的Web应用(包括Django生态常用的dj-database-url配置插件),都会优先读取环境变量中的POSTGRES_HOST值,直接覆盖你在settings.py里写死的HOST=db配置,导致应用实际尝试连接的地址仍然是容器内部的localhost,自然无法连通外部的db容器。
直接删除db服务environment块中那行- POSTGRES_HOST=localhost即可。 - 验证Web容器内实际生效的数据库HOST配置
即使配置了代码目录的卷挂载,也可能存在修改未保存、多环境配置分支覆盖的问题。可以执行以下命令进入web容器,直接查看应用实际加载的数据库HOST值:docker-compose exec web python manage.py shell -c "from django.conf import settings; print(settings.DATABASES['default']['HOST'])"
如果命令输出为localhost而非预期的db,说明要么你修改的settings.py文件没有同步到容器挂载路径下,要么被其他环境变量覆盖了配置。 - 增加Postgres服务就绪等待逻辑
depends_on参数仅能控制容器的启动先后顺序,无法保证Postgres服务完成初始化流程(首次启动需要创建数据目录、初始化数据库实例、创建指定用户和数据库,通常需要数秒时间)。如果web应用在Postgres完全就绪前就发起连接,也会抛出连接失败类报错。
可以在web服务的启动命令中增加等待逻辑,例如搭配wait-for-it工具:command: sh -c "./wait-for-it.sh db:5432 -- python manage.py runserver 0.0.0.0:8000" - 确认两个服务处于同一docker-compose网络
同一份docker-compose.yml下定义的服务会默认加入同一个共享桥接网络,可直接通过服务名互相解析。如果手动修改过网络配置导致web和db不在同一网络,也会出现连接异常,可通过docker network inspect命令确认两个容器是否属于同一个网络。
修正后的参考docker-compose配置
version: '3.7' services: web: container_name: web build: context: . dockerfile: Dockerfile command: python manage.py runserver 0.0.0.0:8000 volumes: - .:/usr/src/web/ ports: - 8000:8000 - 3000:3000 stdin_open: true depends_on: - db db: container_name: db image: postgres:12.0-alpine volumes: - postgres_data:/var/lib/postgresql/data/ environment: - POSTGRES_HOST_AUTH_METHOD=trust - POSTGRES_USER=admin - POSTGRES_PASSWORD=pass - POSTGRES_DB=mydb volumes: postgres_data:
内容的提问来源于stack exchange,提问作者Peter
相关产品推荐
相关产品推荐

