背景
我的个人笔记通过开源的trilium note项目以docker方式搭建的,由于笔记数据比较重要,所以需要进行定时备份,以防丢失。
考虑过的方案有:
(1) 直接备份整个虚拟机,比较笨重,所以不考虑。
(2) 通过rsync等方式配合cron job来同步挂载的数据目录,比较简单粗暴,而且由于数据目录里有sqlite数据库,这种以普通文件方式的来备份的方式可能会埋下文件数据不一致的坑
(3) 通过docker项目docker-volume-backup来备份,该方式会先停止运行待备份的docker容器,避免相应的数据读写问题,然后根据配置备份指定的目录或卷。下面就这种方式进行简要讲解。
待备份的业务容器
业务容器名称为:trilium_note,已经运行中。
数据在主机上的挂载目录为:
~/data/trilium_note/trilium-data -> /root/trilium-data
可通过以下命令查看
sudo docker inspect -f '{{range .Mounts}}{{.Source}} -> {{.Destination}}{{"\n"}}{{end}}' trilium_not
e
原来的trilium_note容器,其docker compose 文件如下(在~/data/trilium_note目录下)
version: '3'
services:
trilium-cn:
image: nriver/trilium-cn
restart: always
container_name: trilium_note
ports:
- "8081:8080"
volumes:
# 把同文件夹下的 trilium-data 目录映射到容器内
- ./trilium-data:/root/trilium-data
environment:
# 环境变量表示容器内笔记数据的存储路径
- TRILIUM_DATA_DIR=/root/trilium-data
用于备份操作的服务容器
服务容器名称为:backup_trilium,以docker compose的方式运行,用于备份前面提及的业务容器(数据)
创建数据保存目录
mkdir ~/data/docker_volume_backup
进入到数据目录
cd ~/data/docker_volume_backup
创建docker配置文件
nano docker-compose.yaml
输入以下内容
services:
# ========== 备份 Trilium Note:每天 8:00 和 23:00,保留 5 天 ==========
backup_trilium:
image: offen/docker-volume-backup:v2.43.2
container_name: backup_trilium
restart: unless-stopped
volumes:
- /var/run/docker.sock:/var/run/docker.sock:ro
- /home/ken/data/trilium_note:/backup/source:ro
- /home/ken/data/docker_backup_data/trilium_note:/archive
- /etc/localtime:/etc/localtime:ro
- /etc/timezone:/etc/timezone:ro
environment:
BACKUP_SOURCES: /backup/source
BACKUP_CRON_EXPRESSION: "0 8,23 * * *"
BACKUP_FILENAME: "trilium_note-backup-%Y-%m-%dT%H-%M-%S.tar.gz"
BACKUP_PRUNING_PREFIX: "trilium_note-backup-"
BACKUP_RETENTION_DAYS: "5"
BACKUP_LATEST_SYMLINK: "trilium_note-backup-latest.tar.gz"
BACKUP_STOP_DURING_BACKUP_LABEL: trilium_note
简要简析:
- docker.sock的挂载:Docker 通信接口。让备份容器能通过这个 socket 向 Docker 引擎发指令(停/启业务容器)。
:ro表示只读,最小权限原则。 - /home/ken/data/trilium_note:/backup/source:ro:把宿主机的 Trilium 数据目录挂载到容器内的
/backup/source,备份工具从这里读取文件打包。:ro只读,防止误改业务数据。 - ~/data/docker_backup_data/trilium_note:/archive:容器打包好的
.tar.gz会写到/archive,映射到宿主机的 ~/data/docker_backup_data/trilium_note/,这样备份文件就持久化在宿主机上了。 - BACKUP_SOURCES: /backup/source:告诉备份工具要备份哪个目录(对应上面 volumes 挂载的容器内路径)。
启动服务容器
sudo docker compose up -d
手动备份
sudo docker exec backup_trilium backup
完成后,在~/data/docker_backup_data/trilium_note/目录下可以看到
恢复备份(测试)
先停止原来的容器(避免新容器启动时端口冲突)
cd ~/data/trilium_note
sudo docker compose down
将最新的备份文件解压到一个新的目录(~/trilium_note_new)
mkdir -p ~/trilium_note_new
tar xzf ~/data/docker_backup_data/trilium_note/trilium_note-backup-latest.tar.gz --strip-components=2 -C ~/trilium_note_new
备注:因为解压时多了两层目录/backup/source,所以通过--strip-components=2参数跳过
进入到新的数据目录
cd ~/trilium_note_new
重新启动容器
sudo docker compose up -d
重新访问主页