You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.19 18:01:10