使用 Docker 部署网站、笔记工具或其他应用时,有时会遇到这样的情况:更新镜像并重新启动项目后,原来的账号、配置和内容突然不见了,页面又回到了首次安装的状态。
这种现象可能由多种原因引起,例如挂载目录发生变化、应用连接到了新的数据库,或者新容器使用了另一个数据卷。先确认旧数据的位置,才能判断接下来应该修复配置,还是从备份恢复。
发现异常后,先保留现有容器、项目目录和数据卷,暂停清理操作。下面以 Linux 服务器上的 Docker 环境为例进行排查,文中的 myapp、/opt/myapp/data 和 /app/data 都是示例,请替换成实际项目使用的名称与路径。
一、先确认更新过程中是否重建了容器
重启同一个容器时,容器可写层中的文件通常还会保留。但更新镜像时,部署工具可能会删除旧容器,再创建一个新容器。旧容器被删除后,只存在于其可写层中的数据也会随之丢失。
因此,应用产生的数据库、上传文件和配置,需要放到正确配置的持久化存储中,例如宿主机绑定目录或 Docker 数据卷。
还要注意,持久化存储和备份解决的是不同问题。持久化让数据独立于容器保存,备份则用于应对误删、损坏和更新失败。
二、检查容器是否挂载了正确的数据目录
先查看服务器上的容器:
docker ps -a
找到目标容器后,检查它的挂载信息:
docker inspect myapp --format \
'{{range .Mounts}}{{println .Type .Source "->" .Destination}}{{end}}'
如果输出类似下面的内容:
bind /opt/myapp/data -> /app/data
表示服务器上的 /opt/myapp/data 被挂载到了容器内的 /app/data。
需要核对两个位置:宿主机目录是否仍然存放着原来的数据,以及容器内路径是否与应用实际使用的数据目录相符。如果应用把数据库写在其他位置,即使配置了挂载,也可能没有保存到需要持久化的数据。
没有看到相关挂载时,还应检查应用是否使用外部数据库、对象存储等服务,不能仅凭挂载列表判断数据已经被删除。

三、核对项目目录有没有发生变化

不少 Compose 项目会使用相对路径,例如下面这个服务配置片段:
volumes:
- ./data:/app/data
在常见的单个 Compose 文件部署方式下,./data 会根据 Compose 文件所在的项目目录解析。
假设原来的项目放在 /opt/myapp,后来只把 Compose 文件复制到了 /home/myapp,那么新部署可能读取 /home/myapp/data,而原来的数据仍保存在 /opt/myapp/data。
可以分别检查这两个示例目录:
ls -lh /opt/myapp/data
ls -lh /home/myapp/data
如果旧目录中仍有数据库或附件,而新目录为空,就需要继续核对挂载配置。先确认文件所属项目、修改时间和备份情况,再考虑调整路径。
另外,把一个空目录绑定到容器中已有文件的目录,会遮住该位置原本可见的内容。新增挂载不会自动把旧容器里的业务数据迁移到宿主机目录。
四、检查是否使用了新的数据卷
使用命名数据卷的项目,还需要检查 Compose 项目名称是否发生变化。
Compose 默认会根据项目目录名称确定项目名。在没有显式指定卷名称的情况下,项目名变化可能使新部署使用另一组数据卷。例如,旧卷叫 myapp_data,新部署却使用了 myapp2_data。
先列出数据卷,再查看疑似旧卷的信息:
docker volume ls
docker volume inspect myapp_data
重点查看卷名称和标签,并与当前容器完整 docker inspect 输出中的 Mounts.Name 对照,确认应用实际使用的是哪个卷。
项目名还可能通过启动参数、环境变量或 Compose 文件中的顶层 name 设置。排查时,应对照更新前后的配置和启动方式。
发现旧数据卷后,先保留并备份。不要因为它暂时没有被容器使用,就将其作为无用资源清理。

五、回看更新时是否执行过数据清理
普通的 docker compose down 默认会移除相关容器和网络,不会默认删除命名数据卷。不过,旧容器可写层中的数据仍会随着容器删除而丢失。
如果执行时添加了 -v 参数,则会删除 Compose 文件中声明的非外部命名卷,以及附加在容器上的匿名卷。
匿名卷还有一个容易忽略的特点:即使普通 down 没有删除它,后续 up 也不会自动重新挂载原来的匿名卷。需要长期保存的数据,应明确使用命名卷或固定的绑定目录。
如果更新期间还执行过卷清理、目录删除或面板中的“删除数据”操作,应结合操作记录确认影响范围。数据卷已经被删除时,重新创建同名卷并不能找回原来的内容。
六、查看数据库连接和权限错误
挂载目录和数据卷正确,也不代表应用一定能读取数据。数据库路径改变、运行用户变化或连接配置错误,都可能让应用启动异常,或者连接到一个空数据库。
进入实际的 Compose 项目目录后查看日志:
cd /opt/myapp
docker compose logs --tail 100
重点关注数据库文件无法打开、权限不足、连接失败、数据迁移失败等提示。
如果日志出现 unable to open database file,应结合应用配置检查数据库路径和目录权限;出现 permission denied 时,则需要核对文件所有者、容器运行用户及挂载是否为只读。
使用外部数据库的项目,还应核对数据库地址、端口和库名,确认更新后的应用仍然连接原来的业务数据库。
权限问题应按应用要求修正,避免直接给整个数据目录开放所有权限。

七、找到旧数据后,先备份再恢复使用
确认旧目录或旧数据卷仍在后,先备份,再调整应用配置。
对于数据库,应使用对应数据库支持的备份方式;需要复制数据库文件时,应按照应用文档停止相关写入,并保留完整的数据文件集合。直接复制正在写入的数据库文件,可能得到不一致的备份。
随后核对应用版本与数据格式是否兼容,再让应用连接正确的目录、数据卷或数据库。不要让两个应用实例同时写入同一份原本只供单实例使用的数据。
恢复后,除了确认能够登录,还要抽查历史记录、附件和关键配置。如果更新过程中已经执行过数据库迁移,也不要直接假定旧版本能够读取迁移后的数据。
如果原始数据已被删除,应优先检查应用备份、数据库备份和更新前的服务器快照。是否能够恢复,取决于备份是否完整,以及数据删除后的实际情况。
八、更新前固定数据位置,并验证备份
日常部署时,建议记录项目目录、容器数据路径、数据卷名称和数据库连接方式。调整部署目录或 Compose 项目名时,也要同步核对这些信息。
更新前保存 Compose 文件、环境配置以及业务数据备份,并查看应用的版本说明。涉及数据库结构变化的更新,应提前确认迁移要求和回退限制。
备份还需要验证:能否正常读取,是否包含附件,是否能够恢复到可用状态。至少保留一份独立于当前服务器的备份,可以减少单台服务器故障带来的影响。
遇到 Docker 更新后数据突然消失的情况,可以按照“当前挂载、旧项目目录、旧数据卷、清理记录、应用日志”的顺序逐项检查。先弄清楚应用正在读取哪份数据,再采取恢复措施,处理过程会更稳妥。








