为何重建Docker镜像/执行docker-compose build后PostgreSQL数据未丢失?为何需数据卷?
Docker Compose中PostgreSQL数据持久化的常见疑问解答
先看看你的Docker Compose配置:
version: '3' services: db: image: postgres web: build: . command: python3 manage.py runserver 0.0.0.0:8000 volumes: - .:/code ports: - "8000:8000" depends_on: - db
接下来逐个解答你的疑问:
1. 重建Docker镜像或执行docker-compose build --force-rm --no-cache .后,PostgreSQL数据为啥没丢?
其实这个现象很好理解,咱们得先搞清楚几个核心点:
- 你执行的
docker-compose build命令,只负责构建指定服务的镜像——在你的配置里,只有web服务是用build: .自定义构建的,db服务直接用的是官方现成的postgres镜像,所以这个build命令根本不会碰db相关的容器和数据。 - 哪怕你重建了
web的镜像,db容器本身并没有被删除或重建,它一直在后台运行(除非你手动停掉并删除它)。而PostgreSQL的数据默认存在db容器内部的/var/lib/postgresql/data目录里,只要容器还在,这个目录里的数据就不会消失。 - 就算你重启
db容器,只要容器没被删除,数据依然会保留在容器的内部存储里。只有当你彻底删除db容器(比如用docker-compose down -v或者docker rm <db容器ID>),容器内部的存储才会被清理,数据才会丢失。
2. 如果这是正常现象,那为啥还要为数据目录创建Docker Volume?
虽然容器内部存储能暂时保留数据,但它有不少明显的短板,这就是咱们需要用Docker Volume的原因:
- 数据安全风险高:如果不小心删除了
db容器(比如误执行docker-compose down -v,或者手动删错容器),容器内部的存储会被直接清理,数据就彻底没了。而用Volume的话,数据是存在宿主机的专门存储区域里,就算容器被删除,Volume里的数据依然保留。 - 迁移和备份更方便:Volume可以独立于容器存在,你可以轻松把Volume的数据打包备份到其他地方,或者迁移到另一台机器上。如果用容器内部存储,备份或迁移就得进入容器手动打包数据,麻烦得多。
- 性能更优:Docker的Volume(尤其是命名Volume)是Docker专门优化过的存储方式,性能比容器内部的存储更好,对于数据库这种IO密集型应用来说,差异会更明显。
- 管理更清晰:官方的
postgres镜像其实默认会自动创建一个匿名Volume来存储数据,但匿名Volume的名字是随机字符串,很难识别和管理。如果我们手动创建命名Volume(比如volumes: - postgres_data:/var/lib/postgresql/data),就能清晰知道哪个Volume对应哪个服务的数据,方便后续的维护操作。
内容的提问来源于stack exchange,提问作者user2080105
相关产品推荐
相关产品推荐

