Implement basic volume backup and restore mechanism

This commit implements three new services, specifically:

  - The `container-volume` service, which applies to a specific volume
    name and ensures this exists. This is mainly useful as a dependency
    to other services, as Podman will create named volumes itself if
    needed.

  - The `container-volume-backup` service, which creates a `tar.gz`
    snapshot of the given volume's contents in `/var/lib/backups`.

  - The `container-volume-restore` service, which populates an empty
    volume from a pre-existing file in `/var/lib/backups`, presumably
    created by `container-volume-backup`.

These are then be used to automatically create volume snapshots every 12
hours, rolling over every 7 days.
This commit is contained in:
Alex Palaistras 2021-08-14 22:31:02 +01:00
parent b832deddfe
commit 41328342b3
16 changed files with 80 additions and 22 deletions

View File

@ -19,3 +19,11 @@ systemd:
enabled: true
- name: container-environment@.service
enabled: true
- name: container-volume@.service
enabled: true
- name: container-volume-backup@.service
enabled: true
- name: container-volume-backup@.timer
enabled: true
- name: container-volume-restore@.service
enabled: true

View File

@ -0,0 +1,16 @@
[Unit]
Description=Backup for container volume %I
[Service]
Type=oneshot
ExecStartPre=/bin/install --mode 0700 --directory %S/backups/coreos-home-server/%i
ExecStart=/bin/podman run --replace --pull never --rm --name %p-%i \
--volume %i:/data:z,ro \
--volume %S/backups/coreos-home-server/%i:/backups:z \
--entrypoint /bin/bash docker.io/debian:stable-slim \
-c 'env name="%i-$(date +%%w%%H)" \
tar -cvpzf "/backups/${name}.tar.gz" -C /data . && \
ln --force "/backups/${name}.tar.gz" /backups/%i-latest.tar.gz'
[Install]
WantedBy=multi-user.target

View File

@ -0,0 +1,9 @@
[Unit]
Description=Scheduled backup for container volume %i
[Timer]
OnCalendar=00/12:30
RandomizedDelaySec=15m
[Install]
WantedBy=timers.target

View File

@ -0,0 +1,14 @@
[Unit]
Description=Restore from backup for container volume %I
ConditionFileNotEmpty=%S/backups/coreos-home-server/%i/%i-latest.tar.gz
[Service]
Type=oneshot
ExecStart=/bin/podman run --replace --pull never --rm --name %p-%i --volume %i:/data:z \
--volume %S/backups/coreos-home-server/%i:/backups:z,ro \
--entrypoint /bin/bash docker.io/debian:stable-slim \
-c 'test -n "$(ls -A /data)" && echo "Volume %i is not empty, skipping." && exit 0; \
tar -xvpf "/backups/%i-latest.tar.gz" -C /data'
[Install]
WantedBy=multi-user.target

View File

@ -0,0 +1,11 @@
[Unit]
Description=Container volume for %I
Wants=container-volume-restore@%i.service container-volume-backup@%i.timer
After=container-volume-restore@%i.service
[Service]
Type=oneshot
ExecStart=/bin/sh -c 'podman volume exists %i || podman volume create %i'
[Install]
WantedBy=multi-user.target

View File

@ -1,7 +1,7 @@
[Unit]
Description=Biboumi IRC gateway for XMPP
Wants=container-build@%N.service prosody.service
After=container-build@%N.service prosody.service
Wants=container-build@%N.service container-volume@%N.service prosody.service
After=container-build@%N.service container-volume@%N.service prosody.service
[Service]
Type=notify

View File

@ -1,7 +1,7 @@
[Unit]
Description=Reliable Discord-Client IRC Daemon
Wants=container-build@%N.service
After=container-build@%N.service
Wants=container-build@%N.service container-volume@%N.service
After=container-build@%N.service container-volume@%N.service
[Service]
Type=notify

View File

@ -1,7 +1,7 @@
[Unit]
Description=Dovecot POP3/IMAP server
Wants=container-build@%N.service mariadb.service rspamd.service
After=container-build@%N.service mariadb.service rspamd.service
Wants=container-build@%N.service container-volume@%N.service mariadb.service rspamd.service
After=container-build@%N.service container-volume@%N.service mariadb.service rspamd.service
[Service]
Type=notify

View File

@ -1,7 +1,7 @@
[Unit]
Description=Git server over SSH
Wants=container-build@%N.service
After=container-build@%N.service
Wants=container-build@%N.service container-volume@%N.service
After=container-build@%N.service container-volume@%N.service
[Service]
Type=notify

View File

@ -1,7 +1,7 @@
[Unit]
Description=MariaDB SQL Database
Wants=container-build@%N.service
After=container-build@%N.service
Wants=container-build@%N.service container-volume@%N.service
After=container-build@%N.service container-volume@%N.service
[Service]
Type=notify

View File

@ -1,7 +1,7 @@
[Unit]
Description=NGINX PHP web service for %I
Wants=container-build@%i.service nginx.service nginx-proxy-http@%i.service
After=container-build@%i.service nginx.service
Wants=container-build@%i.service container-volume@%i.service nginx.service nginx-proxy-http@%i.service
After=container-build@%i.service container-volume@%i.service nginx.service
Before=nginx-proxy-http@%i.service
[Service]

View File

@ -1,7 +1,7 @@
[Unit]
Description=Prosody XMPP server
Wants=container-build@%N.service mariadb.service dovecot.service
After=container-build@%N.service mariadb.service dovecot.service
Wants=container-build@%N.service container-volume@%N.service mariadb.service dovecot.service
After=container-build@%N.service container-volume@%N.service mariadb.service dovecot.service
[Service]
Type=notify

View File

@ -1,7 +1,7 @@
[Unit]
Description=Radicale CalDAV and CardDAV server
Wants=container-build@%N.service dovecot.service
After=container-build@%N.service dovecot.service
Wants=container-build@%N.service container-volume@%N.service dovecot.service
After=container-build@%N.service container-volume@%N.service dovecot.service
[Service]
Type=notify

View File

@ -1,7 +1,7 @@
[Unit]
Description=Redis Key-Value Store
Wants=container-build@%N.service
After=container-build@%N.service
Wants=container-build@%N.service container-volume@%N.service
After=container-build@%N.service container-volume@%N.service
[Service]
Type=notify

View File

@ -1,7 +1,7 @@
[Unit]
Description=Rspamd spam filtering system
Wants=container-build@%N.service redis.service
After=container-build@%N.service redis.service
Wants=container-build@%N.service container-volume@%N.service redis.service
After=container-build@%N.service container-volume@%N.service redis.service
[Service]
Type=notify

View File

@ -1,7 +1,7 @@
[Unit]
Description=Spectrum IM Transport for XMPP
Wants=container-build@%N.service prosody.service
After=container-build@%N.service prosody.service
Wants=container-build@%N.service container-volume@%N.service prosody.service
After=container-build@%N.service container-volume@%N.service prosody.service
[Service]
Type=notify