Docker Compose挂载PostgreSQL卷失效:重建容器后数据丢失排查
问题出在PostgreSQL的挂载路径不对!
兄弟,你这是踩了一个新手常犯的小错误:PostgreSQL官方镜像默认的核心数据存储目录是/var/lib/postgresql/data,但你在docker-compose里把db_vol挂载到了/vol/db——这个目录Postgres根本不会往里面写半条数据!
你看db容器的inspect结果里的Mounts部分,能看到两个卷:
- 一个是你定义的
americanos-project_db_vol,挂载到/vol/db,这完全是个摆设; - 另一个是Docker自动创建的匿名卷(那个长串ID的),挂载到了
/var/lib/postgresql/data——这才是Postgres真正存数据的地方!
之前你执行docker-compose down没加-v,这个匿名卷其实还在,但当你重新up --build的时候,Docker可能重新创建了新的匿名卷(或者之前的匿名卷被意外清理了),导致新容器没有旧数据。而且因为你没把命名卷挂对地方,数据根本没落到你以为的db_vol里。
修复方法很简单:
1. 修正docker-compose.yml的db服务配置
把db服务里的volumes改成下面这样,让db_vol直接挂载到Postgres的默认数据目录:
db: image: postgres:11-alpine volumes: - db_vol:/var/lib/postgresql/data # 这里改了路径! environment: - POSTGRES_DB=americanos - POSTGRES_USER=postgres - POSTGRES_PASSWORD=supersecretpassword
2. 清理旧的无效数据(可选)
如果你想彻底清理之前的匿名卷和无效配置,可以先执行:
docker-compose down -v
这个命令会删除容器、网络,同时删掉所有关联的卷(包括那个没用的匿名卷)。然后再重新构建启动:
docker-compose up -d --build
之后你的Postgres数据就会稳稳存在db_vol这个命名卷里了,哪怕你执行docker-compose down(不加-v),下次启动数据也不会丢。
为什么persistent_vol能正常工作?
因为你的app服务是把persistent_vol挂载到了/vol/web,而你的应用代码确实会往这个目录写数据(比如上传的静态文件、媒体文件),路径匹配上了,自然能持久化。而Postgres的情况就是挂载路径完全错配,等于白挂了个空卷。
内容的提问来源于stack exchange,提问作者mode




