Docker Compose 编排 Django、PostgreSQL 和 Redis 服务的核心是通过 `docker-compose.yml` 定义服务依赖、网络和数据卷,推荐使用 `depends_on` 配合 `healthcheck` 确保数据库就绪后再启动应用。
先说结论:使用 Docker Compose 可以将 Django 应用、PostgreSQL 数据库和 Redis 缓存定义为独立服务,通过内部网络通信并实现数据持久化。
- 适合:本地开发环境、测试环境及中小型生产部署场景
- 先准备:编写 Dockerfile 构建 Django 镜像,准备 .env 文件管理敏感变量
- 验收:所有容器状态为 healthy,Django 能成功连接数据库并读取缓存
命令速用版
以下是最小可用的 `docker-compose.yml` 配置片段,包含健康检查与依赖控制:
version: '3.8'
services:
db:
image: postgres:14-alpine
environment:
POSTGRES_DB: ${DB_NAME}
POSTGRES_USER: ${DB_USER}
POSTGRES_PASSWORD: ${DB_PASSWORD}
volumes:
- postgres_data:/var/lib/postgresql/data
healthcheck:
test: ["CMD-SHELL", "pg_isready -U ${DB_USER}"]
interval: 5s
timeout: 3s
retries: 5
redis:
image: redis:alpine
volumes:
- redis_data:/data
web:
build: .
depends_on:
db:
condition: service_healthy
redis:
condition: service_started
command: python manage.py runserver 0.0.0.0:8000
volumes:
postgres_data:
redis_data:启动服务命令:
docker compose up -d为什么会这样
容器化编排解决了多服务依赖启动顺序和数据持久化问题。传统部署需要手动确保数据库先于应用启动,而 Docker Compose 通过 `depends_on` 定义启动顺序,结合 `healthcheck` 确保服务真正可用后再启动依赖方,避免应用因数据库未就绪而报错退出。
分步处理
1. 定义服务依赖关系
在 `docker-compose.yml` 中声明 `db`、`redis` 和 `web` 服务。Django 服务 (`web`) 必须依赖 `db` 和 `redis`。对于数据库,建议使用 `condition: service_healthy` 等待健康检查通过;对于 Redis,通常 `service_started` 即可,除非有特殊持久化要求。
2. 配置健康检查 (Healthcheck)
PostgreSQL 服务需配置 `healthcheck`,使用 `pg_isready` 命令检测数据库是否接受连接。设置 `interval` 为 5s,`retries` 为 5 次,防止误判。
3. 数据持久化配置
使用 `volumes` 将 PostgreSQL 的 `/var/lib/postgresql/data` 和 Redis 的 `/data` 挂载到宿主机命名卷,确保容器重建后数据不丢失。
4. 网络隔离
默认情况下 Compose 会创建独立网络,服务间可通过服务名互相访问。如需更高隔离性,可显式定义 `networks` 并将服务加入同一自定义网络。
怎么验证是否生效
1. 检查容器状态
执行 `docker compose ps`,确认所有服务状态为 `Up`,且数据库服务健康状态显示为 `healthy`。
2. 查看应用日志
执行 `docker compose logs web`,观察 Django 启动日志,确认没有数据库连接拒绝 (Connection Refused) 错误。
3. 验证数据持久化
停止并删除容器 (`docker compose down`),再次启动后,检查数据库中原有数据是否存在。
常见坑
1. 启动竞争条件
仅使用 `depends_on` 而不配置 `healthcheck` 可能导致 Django 在 PostgreSQL 完全准备好之前尝试连接,引发启动失败。需在应用层增加重试机制或依赖健康状态。
2. 敏感信息泄露
避免在 `docker-compose.yml` 中硬编码数据库密码。应使用 `.env` 文件存储 `POSTGRES_PASSWORD` 等敏感变量,并在文件中引用 `${VAR}`。
3. 权限问题
挂载卷时可能遇到权限拒绝错误,尤其是 Linux 宿主机与容器用户 ID 不一致时。需确保容器内进程有权限写入挂载目录。
常见问题
Django 迁移命令在哪里执行?
建议在容器启动前通过 `docker compose run web python manage.py migrate` 手动执行,或在入口脚本中自动执行。
静态文件如何处理?
生产环境建议使用 Nginx 容器处理静态文件,将 Django 收集的静态目录挂载到 Nginx 容器内,避免 Django 直接 serve 静态资源。
如何重置数据库?
执行 `docker compose down -v` 可删除命名卷从而清空数据库数据,操作前务必备考重要数据。
参考来源
1. 使用 Docker Compose 定义服务依赖:构建高可用 Django+PostgreSQL+Redis 架构
2. Docker 化 Django 生产部署:Nginx、PostgreSQL、Redis 与 Celery 全栈方案
3. Docker 多容器编排:Compose 实战教程
4. docker-compose+postsql 多容器部署 django-vue 项目