Docker数据卷volume挂载实战

用Docker跑服务最烦的就是数据丢了。容器一删数据全没,所以必须用volume挂载。我直接说怎么用。 1. 三种挂载方式 -v或–mount两种写法,我推荐用–mount,语义更清楚。 bind mount:把宿主机目录直接挂进去,改宿主机文件容器里马上同步。 volume:Docker管理的存储区,在/var/lib/docker/volumes/下面。 tmpfs:内存里,重启就丢,适合缓存。 2. 实战:MySQL数据持久化 最典型的例子。MySQL容器一删库就没了,必须挂volume。
docker volume create mysql_data
docker run -d \
  --name mysql8 \
  -e MYSQL_ROOT_PASSWORD=123456 \
  --mount source=mysql_data,target=/var/lib/mysql \
  mysql:8.0
删掉容器再跑一个新的,数据还在。验证一下:
docker rm -f mysql8
docker run -d \
  --name mysql8_new \
  -e MYSQL_ROOT_PASSWORD=123456 \
  --mount source=mysql_data,target=/var/lib/mysql \
  mysql:8.0
进容器查表,数据完好。 3. bind mount:开发调试神器 代码改完不想重新build镜像,直接挂源码目录进去。
docker run -d \
  --name myapp \
  -p 8080:8080 \
  --mount type=bind,source=$(pwd)/src,target=/app/src \
  node:18 \
  node /app/server.js
改宿主机src下的文件,容器里立刻生效。热更新都不用重启容器。 注意bind mount的source必须是绝对路径,$(pwd)是取当前目录。 4. 只读挂载 配置文件不想被容器乱改,加readonly。
docker run -d \
  --name nginx \
  -p 80:80 \
  --mount type=bind,source=$(pwd)/nginx.conf,target=/etc/nginx/nginx.conf,readonly \
  nginx:alpine
容器里写这个文件会报错,安全。 5. 多个容器共享数据 两个容器读写同一个volume,典型场景是日志收集。
docker volume create shared_logs

# 应用容器写日志
docker run -d \
  --name app1 \
  --mount source=shared_logs,target=/var/log/app \
  myapp:latest

# 日志收集容器读日志
docker run -d \
  --name log_collector \
  --mount source=shared_logs,target=/logs,readonly \
  logstash:latest
注意读写并发问题,别两个容器同时写同一个文件。 6. 数据卷容器(老式做法) 以前用–volumes-from共享数据,现在少用了,但老项目里还能见到。
docker create -v /data --name data_container busybox
docker run --volumes-from data_container myapp
新项目直接用volume共享就行。 7. 清理volume docker system prune默认不删volume,要加–volumes。
# 删所有未使用的volume
docker volume prune

# 删所有未使用资源,包括volume
docker system prune -a --volumes
小心,删了数据就没了。 8. 备份和迁移 volume本质上就是宿主机目录,打包就行。
# 备份
docker run --rm \
  --mount source=mysql_data,target=/data \
  -v $(pwd):/backup \
  busybox \
  tar czf /backup/mysql_backup.tar.gz /data

# 恢复
docker run --rm \
  --mount source=new_mysql_data,target=/data \
  -v $(pwd):/backup \
  busybox \
  tar xzf /backup/mysql_backup.tar.gz -C /
9. 权限问题 bind mount时,容器里进程的uid和宿主机文件uid必须一致。比如宿主机文件是1000:1000,容器里进程以root跑,可能写不了。 解决方法:创建镜像时指定用户,或者挂载时用:z(SELinux)等参数。简单粗暴就是chmod 777,但生产别这么干。 10. 性能注意 bind mount和volume性能接近,几乎没损耗。tmpfs最快但数据不持久。 生产环境推荐用volume,由Docker管理,备份迁移都方便。bind mount适合开发调试。 实际生产建议 数据库、消息队列这类有状态服务,必须用volume。如果服务器是雨云,它的云硬盘IO不错,挂载后MySQL跑得很稳,性价比也高,适合长期跑容器化服务。 日志、缓存这类可以不用持久化,或者用tmpfs加速。配置文件用bind mount readonly,方便运维改配置。 记住:容器是短暂的,数据是永恒的。不挂volume的容器删了就等着哭。

雨云是国内一家老牌云服务商,提供高性价比的云服务器和虚拟主机。我用它部署了好几个项目,速度和稳定性都不错。通过 https://www.rainyun.com/SAJA_ 注册可以领一张 5折优惠券,有需要的朋友可以看看。

© 版权声明
THE END
喜欢就支持一下吧
点赞11 分享
评论 抢沙发

请登录后发表评论

    暂无评论内容