如何配置Docker与Django、PostgreSQL协同?本地项目部署异常求助
Hey there! Let's walk through how to get your Django project running smoothly with PostgreSQL using Docker, and fix the issue you're seeing when running docker-compose up.
一、基础配置步骤
First, let's make sure you have the core files set up correctly:
1. 编写 Django 服务的 Dockerfile
Create a Dockerfile in your project root with these contents:
# 使用官方 Python 镜像作为基础 FROM python:3.11-slim # 设置工作目录 WORKDIR /app # 复制依赖文件并安装 COPY requirements.txt . RUN pip install --no-cache-dir -r requirements.txt # 复制项目代码 COPY . . # 暴露 Django 服务端口 EXPOSE 8000 # 启动 Django 开发服务器(后续会优化这个命令) CMD ["python", "manage.py", "runserver", "0.0.0.0:8000"]
2. 编写 docker-compose.yml 文件
This file defines both your Django (web) and PostgreSQL (db) services:
version: '3.8' services: web: build: . command: python manage.py runserver 0.0.0.0:8000 volumes: - .:/app ports: - "8000:8000" depends_on: - db environment: - DB_NAME=mydb - DB_USER=myuser - DB_PASSWORD=mypassword - DB_HOST=db - DB_PORT=5432 db: image: postgres:15-alpine volumes: - postgres_data:/var/lib/postgresql/data/ environment: - POSTGRES_DB=mydb - POSTGRES_USER=myuser - POSTGRES_PASSWORD=mypassword volumes: postgres_data:
3. 更新 Django 的 settings.py
Modify the DATABASES section to use the environment variables from docker-compose:
import os DATABASES = { 'default': { 'ENGINE': 'django.db.backends.postgresql', 'NAME': os.environ.get('DB_NAME'), 'USER': os.environ.get('DB_USER'), 'PASSWORD': os.environ.get('DB_PASSWORD'), 'HOST': os.environ.get('DB_HOST'), # 这里要填 docker-compose 里的 db 服务名 'PORT': os.environ.get('DB_PORT'), } }
Also, add ALLOWED_HOSTS = ['*'] (仅用于开发环境) to avoid host validation errors.
二、针对你遇到的问题排查
From the logs you shared, the PostgreSQL container is starting up correctly (listening on 0.0.0.0:5432), but your Django service might be hitting issues connecting to it. Here are the most common fixes:
1. 解决数据库连接时机问题
Django often tries to connect to PostgreSQL before the database is fully initialized. To fix this, add a wait script to your Docker setup:
- Create a simple
wait-for-it.shscript in your project root (a lightweight version works):#!/bin/sh set -e host="$1" shift cmd="$@" until pg_isready -h "$host" -p 5432; do >&2 echo "PostgreSQL is unavailable - sleeping" sleep 1 done >&2 echo "PostgreSQL is up - executing command" exec $cmd - Update your Dockerfile to make it executable:
COPY wait-for-it.sh . RUN chmod +x wait-for-it.sh - Modify the command in docker-compose.yml:
command: ./wait-for-it.sh db -- python manage.py runserver 0.0.0.0:8000
2. 验证数据库配置一致性
Double-check that the DB_NAME, DB_USER, DB_PASSWORD in your Django settings match exactly what's in the postgres service environment variables in docker-compose.yml. Even a tiny typo can break the connection.
3. 重置数据库卷(如果之前有残留数据)
Sometimes old volume data can cause initialization issues. Run these commands to clean up and restart:
docker-compose down -v docker-compose up --build
4. 检查网络连通性
If the above doesn't work, test if the web container can reach the db container:
docker-compose exec web ping db
If it fails, there might be a network misconfiguration, but docker-compose usually sets up a default network automatically for all services.
最后测试
After making these changes, run docker-compose up --build again. You should see Django successfully connect to PostgreSQL and start the server.
内容的提问来源于stack exchange,提问作者reddd__1

