本删站事故发生于 2021 年 8 月 30 日。
事故缘由
2019 年 9 月 27 日,电脑 110 俱乐部的 Wordpress 实例交给了我。我使用了 Docker Compose 来部署应用:docker-compose.yml
当时的内容为:
version: "2.3"
services:
wordpress:
image: wordpress
restart: always
ports:
- "127.0.0.1:8090:80"
environment:
WORDPRESS_DB_PASSWORD: root
mysql:
image: mysql:5.7
restart: always
environment:
MYSQL_ROOT_PASSWORD: root
2021 年 8 月 30 日,因为希望给容器添加 healthcheck,添加了以下几行:
@@ -8,6 +8,12 @@
- "127.0.0.1:8090:80"
environment:
WORDPRESS_DB_PASSWORD: root
+ healthcheck:
+ test: "curl -f http://127.0.0.1"
+ interval: 30s
+ timeout: 5s
+ retries: 1
+ start_period: 10s
mysql:
image: mysql:5.7
restart: always
由于此前多次重启机器,容器均会自动重启(restart: always
),我放低了警惕,没有考虑到更新 docker-compose.yml
后重启服务会删除之前容器。
于是我运行了 docker-compose down && docker-compose up -d
,此时原容器被删除了(访问 127.0.0.1 显示 Wordpress 安装界面,使用 mysql
工具打开数据库显示 wordpress
数据库为空)。
数据找回
为找回数据,我立即停止了被新创建的容器。以 recover deleted docker container
的关键词在 Google 搜索,搜索到了一个 Stackoverflow 上的问题。按照提示在 /var/lib/docker/volumes/
下查找是否有尚未删除的 volume。查看了一下每个 volume,发现了两个 wordpress 目录和一个 mysql 目录。最终通过 mtime 确定了两个最后修改于当日的 volume,且 cd 进去后发现确实一个是 Wordpress,一个是 MySQL。因为不了解,担心 Docker 会有 GC 机制将 unused volume 删除,我便先把这两个 volume 直接复制到了 /
。
好了,现在至少 volume 还在,即使再差也能从文件系统级恢复数据库和 Wordpress 文件。那现在问题变成了:如何恢复服务呢?
服务恢复
-
复制 volume 数据到 named volume。
我使用了 docker_clone_volume.sh,这个 Shell Script 创建了一个 Alpine 容器,将原 volume 和新 volume 挂载到容器内,使用
cp -av src dst
直接复制。 -
修改 docker-compose.yml 文件挂载新的 named volume
@@ -14,8 +14,17 @@ timeout: 5s retries: 1 start_period: 10s + volumes: + - wordpress:/var/www/html mysql: image: mysql:5.7 restart: always environment: MYSQL_ROOT_PASSWORD: root + volumes: + - mysql:/var/lib/mysql +volumes: + wordpress: + external: true + mysql: + external: true
-
重启并恢复服务
docker-compose up -d
后续
- 运维角度最好从 Docker 级别也做好备份
- 问了下林科学家,还好整站在 Dropbox 上有完整备份,不至于删站
- 在涉及到操作之前没有做 volume 的容器的时候一定要谨慎