1
0
Fork 0
mirror of https://github.com/retspen/webvirtcloud synced 2026-11-11 12:46:49 +00:00

feat(appsettings): the panel backs itself up every day

The only backups of the panel were the ones taken by hand before an
update. Now `manage.py backup` writes a new directory under backups/
with a consistent copy of the sqlite database (the backup API, while
the panel runs, checked with PRAGMA integrity_check), the secret key,
the worker's node_id, settings.py, the SSH keys of the panel's user
and, outside Docker, the commit. It keeps the newest 7 (--keep N) and
deletes older ones only after a good backup; a failed one leaves
nothing, and a second run while one runs fails. Files are mode 600,
directories 700: the database holds compute passwords and keys. With
PostgreSQL the database is left out.

It runs daily at 03:15: in Docker from the image's cron into a new
volume, webvirtcloud-backups; otherwise from webvirt-backup.timer,
which the installer and the manual steps install. A backup has the
layout of the update backups, so the restore steps take either.
This commit is contained in:
catborise 2026-11-03 09:32:34 +03:00
parent 6ca65e291a
commit 777057cb19
12 changed files with 264 additions and 24 deletions

View file

@ -3,7 +3,7 @@ set -e
APP_DIR="/srv/webvirtcloud"
DATA_DIR="$APP_DIR/data"
mkdir -p "$DATA_DIR" "/var/www/.ssh"
mkdir -p "$DATA_DIR" "/var/www/.ssh" "$APP_DIR/backups"
# If settings.py doesn't exist, generate from template
if [ ! -f "$APP_DIR/webvirtcloud/settings.py" ]; then
@ -32,12 +32,12 @@ echo "* Running database migrations..."
"$APP_DIR/venv/bin/python3" "$APP_DIR/manage.py" migrate --noinput
# Set proper permissions on runtime and data directories
chown -R www-data:www-data "$DATA_DIR" "/var/www/.ssh"
chown -R www-data:www-data "$DATA_DIR" "/var/www/.ssh" "$APP_DIR/backups"
chown www-data:www-data "$APP_DIR/webvirtcloud/settings.py" 2>/dev/null || true
chmod 700 "/var/www/.ssh" 2>/dev/null || true
# The database holds compute passwords and password hashes; keep it, the
# secret key and settings private to the app user (as the installer does)
chmod 700 "$DATA_DIR"
chmod 700 "$DATA_DIR" "$APP_DIR/backups"
chmod 600 "$DATA_DIR/db.sqlite3" "$APP_DIR/webvirtcloud/settings.py"
for f in "$DATA_DIR/db.sqlite3-wal" "$DATA_DIR/db.sqlite3-shm"; do
if [ -e "$f" ]; then chown www-data:www-data "$f"; chmod 600 "$f"; fi

2
conf/runit/backup.cron Normal file
View file

@ -0,0 +1,2 @@
# Daily panel backup into /srv/webvirtcloud/backups (the webvirtcloud-backups volume); the output goes to docker logs
15 3 * * * root . /etc/container_environment.sh && cd /srv/webvirtcloud && /sbin/setuser www-data venv/bin/python3 manage.py backup > /proc/1/fd/1 2>&1

View file

@ -0,0 +1,11 @@
[Unit]
Description=WebVirtCloud panel backup
[Service]
Type=oneshot
User=www-data
Group=www-data
UMask=0077
WorkingDirectory=/srv/webvirtcloud
EnvironmentFile=-/etc/default/webvirtcloud
ExecStart=/srv/webvirtcloud/venv/bin/python3 /srv/webvirtcloud/manage.py backup

View file

@ -0,0 +1,11 @@
[Unit]
Description=Daily WebVirtCloud panel backup
[Timer]
OnCalendar=*-*-* 03:15
# a backup missed while the server was off runs at the next boot
Persistent=true
RandomizedDelaySec=10min
[Install]
WantedBy=timers.target