POST://docker-data-persistence
带点橘子味的馒头的头像
带点橘子味的馒头

FRONTEND / DESKTOP DEV

返回文章列表

Docker 容器数据持久化的正确姿势:卷、绑定挂载与实战对比

1 分钟· 672 92 次阅读

刚用 Docker 的人几乎都会踩同一个坑:容器删了,数据库和文件全没了。这篇讲清楚 Docker 数据持久化的两把钥匙——卷(volumes)和绑定挂载(bind mounts),以及生产环境怎么选。

为什么容器会丢数据

Docker 容器由「可写层」承载文件。容器删除时,可写层一并销毁。任何没写进挂载点的数据,都会随容器消失

docker run -d --name test -e MYSQL_ROOT_PASSWORD=x mysql:8
docker rm -f test          # 数据没了

两种持久化方式

1. 卷(Volumes)

由 Docker 管理,存在 /var/lib/docker/volumes/

docker volume create blog-data
docker run -d -v blog-data:/app/data mysql:8
  • ✅ 推荐优先用:备份简单、跨平台一致、docker volume 命令可管理
  • ❌ 位置隐蔽,想直接编辑文件麻烦

2. 绑定挂载(Bind Mounts)

直接把宿主目录挂进容器:

docker run -d -v /opt/www/site:/app blog
  • ✅ 目录可见可编辑,适合放代码和配置
  • ❌ 依赖宿主路径,权限容易出问题(容器用户 vs 宿主用户)

实战:1Panel 部署博客的选型

最近把博客部署到 1Panel 管理的轻量服务器,数据持久化方案是这样定的:

docker run -d --name blog \
  -v /opt/1panel/www/xlmg:/app \        # 绑定挂载:代码 + 内容 + 数据一体
  -p 127.0.0.1:8080:3000 \
  node:22-alpine

为什么用绑定挂载而不是卷?

  1. 代码要频繁更新——绑定挂载后,宿主机直接替换文件,容器重启即生效;
  2. 数据要和代码同目录——content/(文章)和 data/(留言)都在项目内,一个挂载点全搞定;
  3. 1Panel 面板方便管理——面板里直接看文件、改配置。

但有个新坑:部署解压会覆盖内容。每次更新代码用 tar 解压时,content/ 里的文章可能被本地版本冲掉。解决方案是解压时排除数据目录:

tar -xzf release.tar.gz --strip-components=1 \
  --exclude='content' --exclude='data'

权限问题怎么排查

绑定挂载最常见的报错是 EACCES(权限不足)。排查思路:

# 看容器用户
docker exec blog id

# 看宿主目录权限
ls -la /opt/www/site

# 权限不匹配时,要么改目录属主,要么让容器以 root 跑
chown -R 1000:1000 /opt/www/site

小结

场景 推荐
数据库、缓存等纯数据 卷(Volumes)
代码 + 配置 + 数据混合 绑定挂载(Bind Mounts)
容器重建后要保留数据 必须挂载,否则必丢

核心原则:容器是"无状态"的——一切需要保留的东西,都放到挂载点里。想清楚"删掉容器我会失去什么",就知道该挂载什么了。

相关文章