容器里数据库数据会丢,通常不是数据库坏了,而是数据写在了容器实例的可写层里——实例一删,可写层随之消失。要让数据留下来,需要把数据库目录挂到数据卷或宿主机目录上,并在迁移时按“先备份、再迁数据、后切流量”的顺序操作。本文面向在单台 VPS 上用 Docker 部署站点、跨境电商多站点或 AI 应用的个人站长和开发者,讲清可写层与数据卷的区别、迁移的编号步骤、多环境如何拆分数据卷,以及什么时候单机 Docker 就够用。

为什么删掉容器后数据库数据就没了
Docker 的镜像本身是只读的。容器启动后,Docker 在镜像之上加一层可写层,容器运行期间新建和修改的文件都落在这层里。这层与容器实例绑定:执行 docker rm 删除实例,可写层一并删除;用新镜像重建容器,拿到的是一份干净的可写层。数据库把数据文件写在容器内的 /var/lib/mysql 这类路径下,如果这个路径没有挂载到外部存储,数据就等于放在可写层里,删容器即删数据。
同样的机制也解释了另一个常见疑问:为什么同一台机器上跑两个容器、监听同一个端口会冲突,而两个容器内部的同名目录却互不影响。每个容器有独立的文件系统视图和网络命名空间(namespace,决定进程能看到哪些进程、目录和网卡),所以容器之间默认看不到对方的文件。这层隔离是好事,但它不负责替你保存数据——保存数据要靠数据卷。
数据卷和可写层的区别:什么该放进数据卷
数据卷(volume)由 Docker 管理,存放在宿主机的专用目录下,生命周期独立于容器:删掉容器,卷还在;新建容器时把同一个卷挂回去,数据就回来了。绑定挂载(bind mount)是另一种做法,直接把宿主机上的某个目录映射进容器,适合你想自己控制备份路径、或需要让宿主机上的其他程序也读取这些文件的场景。
判断标准可以简化成一句:会变化、且丢了要命的数据放数据卷;构建时就固定、运行时不变的内容打进镜像。按这个标准,常见内容的归属如下。
- 数据库数据文件、上传的图片附件、站点配置文件:放数据卷或绑定挂载。
- 应用代码、运行时依赖、静态资源:打进镜像,通过镜像版本管理。
- 日志:可以挂出来方便排查,也可以交给日志驱动,取决于你是否需要长期保留。
- AI 模型文件:体积大、更新频率低、又不想每次重建镜像都重新下载,放数据卷更合适。
需要提醒的是,数据卷解决的是“容器删了数据还在”,不解决“宿主机磁盘坏了数据还在”。卷仍然落在这一台 VPS 的磁盘上,异地备份要另外做,后文会给出备份思路。
迁移容器服务时先动数据库还是 Web 层
顺序建议是:先迁数据库,再迁 Web 层,最后切流量。反过来先切 Web 层,新机器上的应用会连到一个还没就绪或数据不完整的数据库,表现为页面报错、写入丢失,排查时容易误判成代码问题。下面按编号给出可执行顺序,适用于单机 Docker 或 docker-compose 部署、从旧 VPS 迁到新 VPS 的场景。
- 盘点数据位置。列出每个容器的数据卷和绑定挂载路径,确认数据库、上传目录、配置文件分别落在哪里。可以用
docker inspect查看容器的挂载信息,重点看Mounts字段。 - 在旧机器上做一致性备份。数据库不要直接复制正在写入的数据文件,优先用数据库自带的导出工具生成逻辑备份;文件类数据用打包工具归档。备份完成后在旧机器上校验文件大小和可读性。
- 在新机器上准备目录与卷。先创建数据卷或宿主机目录,确认磁盘余量足够容纳数据和后续增长,再启动数据库容器。
- 导入数据并验证。把备份导入新机器的数据库,检查表数量、关键表行数和最近写入时间是否与旧机器一致。这一步不通过就不要继续。
- 部署 Web 层并指向新数据库。用同一份 compose 文件或等价配置在新机器拉起 Web 容器,连接串指向新数据库,先在本机用内网地址访问验证页面和写入功能。
- 切换流量并观察。把域名解析或负载入口切到新机器,观察一段时间内的错误日志和数据库连接数。旧机器保持可启动状态一段时间,作为回滚路径。
- 确认稳定后再清理旧环境。删除旧容器和旧数据卷属于不可逆操作,务必在确认新环境稳定、备份已另行保存之后再做。
第 4 步和第 6 步是最容易被跳过、也最容易出问题的两步。迁移期间旧站点如果仍在接受写入,切流量前需要再同步一次增量数据,否则切换瞬间会丢掉这段时间的订单或评论。
一个最小化的 compose 数据卷结构
下面是一个站点加数据库的目录与挂载结构示意,路径和镜像标签按你的实际情况替换。示例只展示数据持久化相关的部分,不涉及具体版本号。
services:
db:
image: <数据库镜像>
volumes:
- db_data:/var/lib/mysql # 数据库数据目录,必须持久化
environment:
- MYSQL_ROOT_PASSWORD=<占位符>
web:
image: <应用镜像>
volumes:
- web_uploads:/app/uploads # 用户上传文件,必须持久化
- ./config:/app/config:ro # 配置文件只读挂载
depends_on:
- db
volumes:
db_data:
web_uploads:
关键点在最后两行的具名卷声明:没有声明具名卷,容器重建后数据就没有稳定的挂载点。配置文件用只读挂载(:ro),避免容器内进程意外改写宿主机上的配置。
同一台 VPS 上多环境并存:按站点和用途拆数据卷
跨境电商团队常在同一台 VPS 上跑多个独立站点,或者同时跑测试环境和正式环境。这时数据卷的拆分原则是“一个站点一套卷,不共用可写目录”。如果两个站点共用一个上传目录或一个数据库实例的同一个库,一个站点的误删、插件冲突或数据导入会直接污染另一个站点。
具体做法:每个站点在 compose 文件里使用带前缀的具名卷,例如站点 A 用 sitea_db、sitea_uploads,站点 B 用 siteb_db、siteb_uploads;数据库尽量一站点一实例,资源紧张时至少做到一站点一独立库并限制各自的内存上限。备份也按站点分别打包,恢复时不会互相牵连。
AI 应用的情况不同:模型文件通常有几百 MB 到数 GB,更新频率低。把它打进镜像会让每次重建都重新拉取一遍,镜像体积也变大;放进数据卷,镜像保持精简,模型更新时只替换卷里的文件。推理服务产生的日志和缓存可以单独挂一个卷,方便清理而不影响模型文件。
单机 Docker 什么时候就够:三个判断条件与配置估算
不是所有场景都需要 Kubernetes(K8s,多机容器编排系统)。满足以下三个条件时,单机 Docker 加 compose 通常就够用:一是只跑在一台机器上,没有跨机高可用要求;二是服务数量在个位数到十几个之间,重启和更新可以接受短暂中断;三是团队里没有人专职维护集群。只要出现“必须多机容灾”“需要按流量自动扩缩容”“多个团队共享一个集群”中的任意一条,才值得考虑编排层。
配置估算按负载类型分开看,以下是经验区间,不是精确公式,实际以监控数据为准:
- 纯建站(Web + 数据库 + 缓存):起步可看 2 核 CPU、2 GB 到 4 GB 内存,数据库和缓存各占一部分内存,磁盘优先选 SSD 类,容量按现有数据量留出数倍增长空间。
- 跨境电商多站点:站点数乘以单站内存需求,再留 20% 到 30% 余量;磁盘要同时容纳多个站点的上传文件和各自的数据库备份。
- AI 推理:内存和显存是主要瓶颈,模型文件占磁盘,加载时占内存,配置要按模型规模单独评估,不能套用建站的经验值。
带宽按计费方式区分:固定带宽适合流量平稳的站点,按流量计费适合波动大的场景,选之前先估算月流量。涉及中国大陆访问时,线路表现与机房、运营商和时段有关,建议在目标用户所在地区做实际测试后再决定,不要只看宣传页的线路名称。
操作提醒
删除数据卷、重建数据库容器、覆盖宿主机目录都属于不可逆操作。执行前先确认备份文件已复制到另一台机器或对象存储,并记下回滚所需的镜像标签和 compose 文件版本。数据卷本身不做异地冗余,单机磁盘故障时卷里的数据同样会丢。
FAQ
数据卷会自动备份吗?
不会。数据卷只是把数据从容器可写层挪到宿主机上的独立位置,备份仍需自己安排:定期把卷目录打包,或对数据库执行逻辑导出,再把备份文件传到另一台机器或对象存储。备份频率按你能接受的数据丢失窗口来定。
误删了容器,数据还能恢复吗?
如果数据在具名卷或绑定挂载里,删容器不影响数据,用同一挂载点重建容器即可。如果数据只写在可写层里,容器删除后可写层随之删除,通常无法通过 Docker 自身恢复,只能依赖之前做过的备份。
数据库容器可以直接复制数据文件做备份吗?
不建议在数据库运行且持续写入时直接复制数据文件,可能得到不一致的副本。优先使用数据库自带的导出工具,或在停机窗口内做文件级备份。
多个站点共用一台 VPS,怎么防止互相影响?
按站点拆分数据卷和数据库,给每个容器设置内存上限,避免一个站点占满内存拖垮其他站点。备份和恢复也按站点独立进行。
模型文件放数据卷还是打进镜像?
体积大、更新不频繁的模型文件放数据卷更合适,镜像保持精简、重建更快;模型版本需要严格可追溯时,可以在卷内按版本分目录管理。
落地时可以先做两件事:把现有容器的挂载关系逐个查清,确认数据库和上传目录是否真的落在卷上;再按目标用户所在地区测试线路和磁盘写入表现,据此决定 VPS 的 CPU、内存和磁盘规格。规格和计费以对应服务商产品页的当前信息为准,发布前核对。
本文由网上采集发布,不代表我们立场,转载联系作者并注明出处:https://www.uuccloud.com/11875.html
