Docker Compose:如何避免容器构建时数据库卷被清空
PostgreSQL卷重建导致数据丢失的解决办法
问题背景
每次修改代码后执行部署命令:
docker-compose -f docker-compose.yml -f docker-compose.stage.yml up -d --build
重建容器时,PostgreSQL的postgres_data卷会被重新创建,导致现有数据丢失,执行迁移后无历史数据。
核心原因分析
命名卷postgres_data默认是持久化的,不会被docker-compose up --build自动删除。数据丢失通常来自以下场景:
- 部署流程中误执行了
docker-compose down -v(带-v参数会删除所有关联卷) - 卷被手动删除,或EC2实例上的Docker环境因磁盘清理等原因移除了卷
- 极少数情况下,配置合并冲突导致卷未正确关联
解决方案
1. 修正部署流程,避免删除卷
- 禁止使用
docker-compose down -v命令,如需清理容器,使用docker-compose down(不带-v),保留卷数据 - 部署时仅构建需要更新的服务,无需重启db服务:
docker-compose -f docker-compose.yml -f docker-compose.stage.yml up -d --build web celery celery-beat
2. 验证卷的存在性
每次部署前检查卷是否存在:
docker volume ls | grep postgres_data
若卷不存在,需从备份恢复数据,或手动创建卷后重新初始化。
3. 为卷添加外部属性(强制持久化)
修改docker-compose.stage.yml中的volumes配置,添加external: true,避免Docker Compose自动删除卷:
volumes: postgres_data: external: true static_volume: media_volume:
添加前需手动创建卷:
docker volume create postgres_data
4. 检查entrypoint脚本与迁移逻辑
- 确认
entrypoint.sh中的migrate命令无破坏性参数(如--run-syncdb会跳过迁移直接同步,可能导致数据结构异常) - 检查Django迁移文件,确保没有误删除表或数据的操作
5. 确认db服务的卷配置正确性
确保docker-compose.stage.yml中的db服务卷映射正确指向PostgreSQL数据目录:
db: image: postgres:12.0-alpine container_name: xxx_stage_db volumes: - postgres_data:/var/lib/postgresql/data/ env_file: - .env.db
该配置是PostgreSQL持久化数据的标准写法,无需修改。
内容的提问来源于stack exchange,提问作者vinchuli
相关产品推荐
相关产品推荐

