Docker Compose部署Django项目时PostgreSQL主机名解析失败
问题解决:Docker Compose中PostgreSQL主机名解析失败
问题描述
执行docker-compose up启动基于Django、PostgreSQL、Redis、Channels的Docker项目时,出现以下错误:
django.db.utils.OperationalError: could not translate host name "postgres_db" to address: Temporary failure in name resolution
PostgreSQL镜像已创建并可在Docker Desktop中查看,但无法被Django容器识别。
提供的配置文件
docker-compose.yml
version: "3.5" services: redis: image: redis:latest networks: - redisnet postgres_db: image: postgres volumes: - ./data/db:/var/lib/postgresql/data environment: - POSTGRES_DB=postgres - POSTGRES_USER=postgres - POSTGRES_PASSWORD=postgres django_wsgi: container_name: django_wsgi build: context: . command: uwsgi --socket=:9000 --module=core.wsgi:application --py-autoreload=1 volumes: - .:/code env_file: - .env networks: - webnet - redisnet links: - redis - postgres_db:postgres_db depends_on: - postgres_db django_asgi: container_name: django_asgi build: . # command: python manage.py runserver 0.0.0.0:8002 command: daphne -b 0.0.0.0 -p 8002 core.asgi:application env_file: - .env volumes: - .:/code networks: - webnet - redisnet links: - redis - postgres_db:postgres_db depends_on: - postgres_db nginx: image: nginx:1.15.0 depends_on: - django_asgi - django_wsgi volumes: - ./nginx:/etc/nginx/conf.d - ./static:/static networks: - webnet ports: - "80:80" networks: webnet: redisnet:
Dockerfile
FROM python:3.8 ENV PYTHONUNBUFFERED 1 ENV REDIS_HOST "redis" RUN mkdir /code WORKDIR /code RUN pip install --upgrade pip RUN pip install psycopg2 COPY requirements.txt /code/ RUN pip install uwsgi RUN apt-get update && apt-get install -y tdsodbc unixodbc-dev RUN pip install -r requirements.txt ADD . /code/
nginx default.conf
upstream django_wsgi { server django_wsgi:9000; } upstream django_asgi { server django_asgi:8002; } map $http_upgrade $connection_upgrade { default upgrade; '' close; } server { listen 80 default_server; root /usr/src/app; index index.html; client_max_body_size 60M; location / { include /etc/nginx/uwsgi_params; uwsgi_pass django_wsgi; uwsgi_param Host $host; uwsgi_param X-Real-IP $remote_addr; uwsgi_param X-Forwarded-For $proxy_add_x_forwarded_for; uwsgi_param X-Forwarded-Proto $http_x_forwarded_proto; } location /chat/stream/ { proxy_pass http://django_asgi; proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection $connection_upgrade; proxy_redirect off; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Host $server_name; } location /static { alias /static; } }
解决方案
1. 修复PostgreSQL的网络配置
核心问题:postgres_db服务未加入任何自定义网络,导致Django容器所在的webnet/redisnet无法通过主机名访问它。
修改docker-compose.yml中的postgres_db服务,添加网络配置:
postgres_db: image: postgres volumes: - ./data/db:/var/lib/postgresql/data environment: - POSTGRES_DB=postgres - POSTGRES_USER=postgres - POSTGRES_PASSWORD=postgres networks: # 添加这部分 - webnet - redisnet
2. 移除过时的links配置
Docker Compose的links是过时特性,在自定义网络中,服务名本身即可作为主机名解析,直接删除django_wsgi和django_asgi中的links字段:
# 从django_wsgi和django_asgi中删除以下内容 links: - redis - postgres_db:postgres_db
3. 添加PostgreSQL健康检查(可选但推荐)
depends_on仅保证容器启动顺序,不保证PostgreSQL服务已就绪。添加健康检查确保Django容器在PostgreSQL可用后再启动:
postgres_db: image: postgres volumes: - ./data/db:/var/lib/postgresql/data environment: - POSTGRES_DB=postgres - POSTGRES_USER=postgres - POSTGRES_PASSWORD=postgres networks: - webnet - redisnet healthcheck: # 添加健康检查 test: ["CMD-SHELL", "pg_isready -U postgres"] interval: 5s timeout: 5s retries: 5
同时修改django_wsgi和django_asgi的depends_on,依赖PostgreSQL的健康状态:
depends_on: postgres_db: condition: service_healthy
4. 验证Django数据库配置
确保.env或settings.py中的数据库主机配置为postgres_db:
# settings.py示例 DATABASES = { 'default': { 'ENGINE': 'django.db.backends.postgresql', 'NAME': 'postgres', 'USER': 'postgres', 'PASSWORD': 'postgres', 'HOST': 'postgres_db', # 必须和docker-compose中的服务名一致 'PORT': '5432', } }
操作步骤
- 停止当前运行的容器:
docker-compose down - 按照上述修改更新配置文件
- 重新构建并启动容器:
docker-compose up --build
内容的提问来源于stack exchange,提问作者turyanazizov
相关产品推荐
相关产品推荐

