Docker化Django应用无法连PostgreSQL问题排查及Docker localhost解析咨询
Django容器化数据库连接失败问题解决及Docker localhost解析
我尝试将Django应用容器化,相关配置如下:
现有配置
settings.py
DATABASES = { 'default': { 'ENGINE': 'django.db.backends.postgresql_psycopg2', 'NAME': 'DB_NAME', 'USER': 'DB_USER', 'PASSWORD': 'DB_PASSWORD', 'HOST': 'localhost', 'PORT': '5432', } }
.env文件
POSTGRES_USER='DB_USER' POSTGRES_PASSWORD='DB_PASSWORD' POSTGRES_DB='DB_NAME' POSTGRES_HOST='localhost' POSTGRES_PORT='5432'
Dockerfile.web
FROM python:3.9-bullseye WORKDIR /app ENV PYTHONUNBUFFERED=1 COPY csgo . RUN apt-get update -y \ && apt-get upgrade -y pip \ && pip install --upgrade pip \ && pip install -r requirements.txt CMD ["python", "manage.py", "runserver", "0.0.0.0:8000"]
docker-compose.yml
version: '3' services: web: container_name: web build: context: . dockerfile: Dockerfile.web env_file: - .env volumes: - .:/code ports: - '8000:8000' depends_on: - db db: image: postgres:13 restart: always ports: - '5432:5432' env_file: - .env volumes: postgres_data:
执行docker-compose up后,数据库连接失败,报错:
django.db.utils.OperationalError: could not connect to server: Connection refused web | Is the server running on host "localhost" (127.0.0.1) and accepting web | TCP/IP connections on port 5432? web | could not connect to server: Cannot assign requested address web | Is the server running on host "localhost" (::1) and accepting web | TCP/IP connections on port 5432?
问题解决步骤
1. 修改数据库连接的HOST配置
容器内的localhost指向容器自身,而非宿主机或其他容器。在Docker Compose的默认网络中,服务名可作为域名直接解析到对应容器的IP,所以需要将数据库连接的HOST改为db(即docker-compose.yml中定义的数据库服务名):
更新.env文件
将POSTGRES_HOST的值从localhost改为db:
POSTGRES_USER='DB_USER' POSTGRES_PASSWORD='DB_PASSWORD' POSTGRES_DB='DB_NAME' POSTGRES_HOST='db' POSTGRES_PORT='5432'
更新settings.py
让Django读取环境变量中的数据库配置,保证灵活性:
import os DATABASES = { 'default': { 'ENGINE': 'django.db.backends.postgresql_psycopg2', 'NAME': os.getenv('POSTGRES_DB'), 'USER': os.getenv('POSTGRES_USER'), 'PASSWORD': os.getenv('POSTGRES_PASSWORD'), 'HOST': os.getenv('POSTGRES_HOST', 'db'), 'PORT': os.getenv('POSTGRES_PORT', '5432'), } }
2. 完善数据库服务的持久化配置(可选但推荐)
为了避免容器重启后数据库数据丢失,需要给db服务挂载postgres_data卷:
修改docker-compose.yml中的db服务部分:
db: image: postgres:13 restart: always ports: - '5432:5432' env_file: - .env volumes: - postgres_data:/var/lib/postgresql/data
3. 重新启动服务
执行以下命令重启容器:
docker-compose down docker-compose up --build
Docker容器中localhost的定义及连接机制
- 容器内的localhost:每个Docker容器拥有独立的网络命名空间,容器内的
localhost(127.0.0.1)仅指向容器自身,无法访问宿主机或其他容器的服务。 - Docker Compose的服务通信:Docker Compose会自动为所有服务创建一个默认的桥接网络,同一网络内的容器可以通过服务名直接通信。服务名会被Docker内置的DNS解析为对应容器的IP地址,这也是为什么我们可以用
db作为数据库HOST的原因。 - depends_on的作用:
depends_on仅保证web服务在db服务启动后再启动,但不保证数据库服务完全就绪。如果需要等待数据库初始化完成,可以添加健康检查或使用wait-for-it类工具实现等待逻辑。
内容的提问来源于stack exchange,提问作者Docker
相关产品推荐
相关产品推荐

