使用 Docker Compose 编排 Django、PostgreSQL 和 Redis 是目前实现开发环境与生产环境一致性的主流方案,特别适合需要快速搭建本地栈或进行容器化部署的团队。
先说结论:通过声明式 YAML 文件定义服务依赖与健康检查,能显著降低环境配置成本并避免“在我机器上能运行”的问题。
- 适合:本地开发、测试环境。生产环境建议使用 Kubernetes 或配合 Nginx+Gunicorn 部署。
- 先准备:规划好目录结构,确认 PostgreSQL 和 Redis 的镜像版本及持久化卷,准备好 .env 环境变量文件。
- 验收:检查容器日志无报错,Django 能成功连接数据库和缓存服务。
命令速用版
# 创建环境变量文件
cp .env.example .env
# 启动所有服务
docker-compose up -d
# 查看服务状态
docker-compose ps
# 查看应用日志
docker-compose logs -f web
# 执行数据库迁移
docker-compose run web python manage.py migrate为什么会这样
传统部署方式需要手动在服务器上安装 Python 环境、配置数据库和网络,每一步都可能遇到版本兼容性问题。Docker Compose 通过容器化技术将这些步骤标准化,环境即代码的理念让基础设施可以版本化、可重复、可共享。每个服务运行在独立容器中,互不干扰,无论是在 Mac、Windows 还是 Linux 上,行为一致。
通过 Compose 定义依赖,可以实现 PostgreSQL 数据库的优雅初始化,以及 Redis 缓存的故障自动恢复,让服务依赖管理从“能用”进化到“高可用”。
分步处理
1. 规划项目结构
建议采用清晰的目录结构,将 Docker 配置文件与业务代码分离。例如在根目录下创建 compose 目录区分环境,或直接在根目录放置 docker-compose.yml。
my_django_app/
├── Dockerfile
├── docker-compose.yml
├── .env
├── .env.example
├── requirements.txt
└── django_app/
├── manage.py
└── django_app/2. 编写 Dockerfile
定义 Web 容器的构建规则,基础镜像建议选择官方 Python 镜像,安装依赖后设置工作目录。
FROM python:3.9
ENV PYTHONDONTWRITEBYTECODE=1
ENV PYTHONUNBUFFERED=1
WORKDIR /app
COPY requirements.txt .
RUN pip install -r requirements.txt
COPY . .
# 生产环境请改用 gunicorn 启动
CMD ["python", "manage.py", "runserver", "0.0.0.0:8000"]3. 配置 docker-compose.yml
定义 web、db 和 redis 三个核心服务。注意使用 volumes 持久化数据库数据,使用 networks 隔离网络。为数据库服务配置 healthcheck,确保应用启动前数据库已就绪。
version: '3.8'
services:
web:
build: .
command: python manage.py runserver 0.0.0.0:8000
volumes:
- .:/app
ports:
- "8000:8000"
depends_on:
db:
condition: service_healthy
redis:
condition: service_started
env_file:
- .env
db:
image: postgres:14-alpine
volumes:
- postgres_data:/var/lib/postgresql/data
environment:
POSTGRES_DB: ${DB_NAME}
POSTGRES_USER: ${DB_USER}
POSTGRES_PASSWORD: ${DB_PASSWORD}
healthcheck:
test: ["CMD-SHELL", "pg_isready -U ${DB_USER}"]
interval: 5s
timeout: 3s
retries: 5
redis:
image: redis:7.2-alpine
volumes:
- redis_data:/data
volumes:
postgres_data:
redis_data:4. 调整 Django 配置
在 settings.py 中,数据库 HOST 应填写 compose 文件中定义的服务名(如 db),而不是 localhost。Redis 连接地址同理。
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': 'db',
'PORT': '5432',
}
}
CACHES = {
'default': {
'BACKEND': 'django.core.cache.backends.redis.RedisCache',
'LOCATION': 'redis://redis:6379/1',
}
}关键配置文件示例
1. .env 文件内容
为了避免敏感信息泄露,不要将 .env 提交到版本控制。以下是示例内容:
DB_NAME=mydb
DB_USER=myuser
DB_PASSWORD=mypassword
SECRET_KEY=your-secret-key-here
DEBUG=12. requirements.txt 依赖列表
确保包含必要的数据库驱动和缓存库:
Django>=4.2,<5.0
psycopg2-binary>=2.9
redis>=4.5
gunicorn>=21.0怎么验证是否生效
启动服务后,首先观察容器状态是否为 Up。进入 Web 容器内部,尝试使用 Django 命令连接数据库。
# 检查容器运行状态
docker-compose ps
# 进入容器执行迁移测试
docker-compose exec web python manage.py migrate
# 测试 Redis 连接
docker-compose exec redis redis-cli ping如果 migrate 命令成功执行且无报错,redis-cli ping 返回 PONG,说明编排成功。同时检查 Web 容器日志,确认没有数据库连接拒绝的错误。
常见坑
1. 数据持久化丢失
如果没有配置 volumes,容器重启后数据库数据会丢失。务必确保 postgres_data 和 redis_data 卷已正确定义并挂载。
2. 服务启动顺序问题
仅使用 depends_on 只能保证启动顺序,不能保证服务就绪。建议配合 healthcheck 使用,或者在应用代码中加入连接重试机制,避免应用启动时数据库尚未准备好导致的崩溃。
3. 网络连通性
容器间通信使用服务名作为主机名,不要在 Django 配置中写 127.0.0.1 或 localhost,否则应用无法找到数据库容器。
生产环境部署建议
Docker Compose 配合 runserver 仅适用于开发和测试环境。生产环境请务必注意以下几点:
- Web 服务器:使用 Gunicorn 或 uWSGI 替代 Django 自带的 runserver。
- 反向代理:在前端配置 Nginx 处理静态文件和 SSL 终止。
- 安全性:关闭 DEBUG 模式,使用强密码策略,限制数据库远程访问。
- 编排工具:大规模生产环境建议迁移至 Kubernetes 或 Docker Swarm 以获得更好的自愈能力和负载均衡。