容器跑着跑着数据没了?
你有没有遇到过这种情况:用 Docker 跑了个博客,写了几篇文章,结果一升级服务,所有内容全没了。别慌,这不是系统出 bug,而是你没做好数据持久化。在容器世界里,容器本身是临时的,重启或重建后,里面的数据默认都会清空。
容器化和数据持久化的矛盾
网络容器化最大的好处是轻量、可复制、启动快。但这也带来一个问题——数据存哪儿?如果直接把数据库、配置文件、用户上传的内容塞进容器,那每次更新镜像或重启服务,数据就丢了,跟手机没备份一样危险。
挂载卷才是正解
解决办法就是用“卷”(Volume)或者绑定挂载(Bind Mount)。简单说,就是把宿主机上的某个文件夹,映射到容器内部,让容器读写这个外部目录。这样即使容器删了重建,数据还在宿主机上。
比如你用 WordPress 搭博客,数据库可以用 MySQL 容器,这时候就应该把数据库文件挂载出来:
docker run -d \
--name mysql-blog \
-e MYSQL_ROOT_PASSWORD=123456 \
-v /data/mysql:/var/lib/mysql \
mysql:5.7
这里的 /data/mysql 是宿主机的目录,/var/lib/mysql 是容器内 MySQL 存数据的地方。只要宿主机这目录不删,数据就不会丢。
端口映射和数据持久化经常一起用
你在做端口映射的时候,比如把容器的 80 端口映射到宿主机的 8080,往往也意味着这个服务需要长期运行,那它产生的数据自然也不能丢。
举个例子,你部署一个 Nextcloud 私有云,既要通过端口映射让外网能访问,又要保证用户上传的文件不丢失:
docker run -d \
--name nextcloud \
-p 8080:80 \
-v /data/nextcloud:/var/www/html \
nextcloud
这里 -p 8080:80 是端口映射,-v /data/nextcloud:/var/www/html 是数据持久化。两个配合,服务可访问,数据也不丢。
别再把数据塞进容器了
新手常犯的错误是把所有东西都打包进镜像,包括配置和初始数据。这样做虽然方便分发,但一旦要修改,就得重新构建镜像,效率低还容易出错。正确的做法是:镜像只管程序,数据交给挂载卷。
另外,生产环境中建议用命名卷(named volume)或 Docker Compose 管理,更清晰也更容易备份。