在家用服务器跑了个 Docker 搭的 Nextcloud,结果某天容器一重启,所有文件全没了。这种情况不少见,尤其是刚开始玩内网穿透和容器化部署的朋友,总以为服务起来了就万事大吉,却忽略了最关键的一环——数据持久化。
容器是临时的,数据不能跟着一起“临时”
Docker 容器本质是无状态的,像一个随时可以销毁再重建的运行环境。你把数据库、配置文件、用户上传的内容直接塞进容器里,就好比把重要文件存在一张随时会丢的U盘上。一旦更新镜像、重启服务或者机器故障,数据就可能彻底消失。
挂载目录才是长久之计
解决办法很简单:把容器内的数据目录映射到宿主机的固定路径。比如你用 MySQL 容器,就把 /var/lib/mysql 挂到本机的 /data/mysql。这样即使容器删了重装,数据还在硬盘上。
常见的启动命令写法:
docker run -d \n --name my-mysql \n -v /data/mysql:/var/lib/mysql \n -e MYSQL_ROOT_PASSWORD=123456 \n mysql:8.0
这里的 -v 参数就是关键,它建立了容器和宿主机之间的“数据通道”。
别忘了权限和路径一致性
实际操作中常遇到的问题是权限错误。比如容器里的 MySQL 进程用 mysql 用户跑,但宿主机上的 /data/mysql 目录属于 root,就会导致启动失败。提前设好目录权限能省去很多麻烦:
chown -R 999:999 /data/mysql
另外,路径尽量用绝对路径,避免相对路径在不同环境下出错。特别是配合 docker-compose 使用时,统一管理更方便。
结合内网穿透,远程也能安心存取
很多人搭容器是为了通过内网穿透把服务暴露到外网,比如用 frp 或 zerotier 访问家里的文件系统。这时候更要确保数据是持久化的。试想你在外连回家里的笔记应用,结果发现昨天写的全没了,那种崩溃感可想而知。
只要数据挂在本地磁盘,不管内网穿透怎么断连重连,服务怎么重启,内容始终都在。这才是真正可靠的私人云。
用命名卷也是一种选择
除了直接挂目录,Docker 还支持命名卷(named volume),适合不想手动管理路径的情况:
docker volume create dbdata
docker run -d \n --name mysql-app \n -v dbdata:/var/lib/mysql \n mysql:8.0
这种方式由 Docker 管理存储位置,更适合标准化部署,但调试时不如直接挂载目录直观。
真实场景提醒
朋友老李用容器搭了个家庭相册系统,没做持久化,结果系统升级后照片全丢,老婆差点跟他吵架。后来他改成了挂载 /photos 到容器里,再通过内网穿透从手机访问,现在全家人都爱用。
技术不难,关键是意识到:容器是“房子”,数据是“家具”。搬新房子可以,但家具不能丢。