From 51d4d1988e05650237eda293d204713747b45e29 Mon Sep 17 00:00:00 2001 From: tkl Date: Mon, 1 Jul 2024 07:39:16 +0200 Subject: [PATCH] Init borgbackup based backup solution for home server --- backup.sh | 56 +++++++++++++++++++++++ borg.sh | 69 +++++++++++++++++++++++++++++ docker/gitea/start.sh | 20 +++++++++ docker/grafana/start.sh | 10 +++++ docker/influx/start.sh | 9 ++++ docker/nextcloud/docker-compose.yml | 27 +++++++++++ update.sh | 49 ++++++++++++++++++++ wake_probook.sh | 36 +++++++++++++++ 8 files changed, 276 insertions(+) create mode 100755 backup.sh create mode 100755 borg.sh create mode 100755 docker/gitea/start.sh create mode 100755 docker/grafana/start.sh create mode 100755 docker/influx/start.sh create mode 100644 docker/nextcloud/docker-compose.yml create mode 100755 update.sh create mode 100755 wake_probook.sh diff --git a/backup.sh b/backup.sh new file mode 100755 index 0000000..8fc8ea4 --- /dev/null +++ b/backup.sh @@ -0,0 +1,56 @@ +#!/bin/sh + +# wake up backup machine +./wake_probook.sh 20 +if [ $? -ne 0 ]; then + echo "Unable to wake up backup machine" + exit 1 +fi + +# stop web server to avoid access +echo "Stopping web server" +systemctl stop nginx + +# nextcloud +echo "Backup nextcloud..." +# docker-compose -f docker/nextcloud/docker-compose.yml down --rmi all +docker-compose -f docker/nextcloud/docker-compose.yml down +./borg.sh Nextcloud /srv/nextcloud +./borg.sh Postgres /srv/postgres-data +docker-compose -f docker/nextcloud/docker-compose.yml up -d + +# gitea +echo "Backup gitea..." +docker stop gitea +# docker rm gitea +# docker rmi gitea/gitea:latest +./borg.sh Gitea /srv/gitea +# docker/gitea/start.sh +docker start gitea + +# influx/grafana +echo "Backup influx/grafana..." +docker stop influx +# docker rm influx +docker stop grafana +# docker rm grafana +# docker rmi influxdb grafana/grafana-oss +./borg.sh Influx /srv/influx +./borg.sh Grafana /srv/grafana +# docker/influx/start.sh +# docker/grafana/start.sh +docker start influx +docker start grafana + +# activitycollect +echo "Backup activitycollect..." +docker stop activitycollect +./borg.sh Activitycollect /srv/activitycollect +docker start activitycollect + +# re-start nginx +echo "Starting nginx" +systemctl start nginx + +# shutdown backup machine +ssh root@probook 'systemctl poweroff' diff --git a/borg.sh b/borg.sh new file mode 100755 index 0000000..68eb446 --- /dev/null +++ b/borg.sh @@ -0,0 +1,69 @@ +#!/bin/sh + +if [ $# -ne 2 ]; then + echo "Missing parameters" + exit 1 +fi + +NAME=$1 +SRC_FOLDER=$2 +USER=tkl +HOST=probook + +# Setting this, so the repo does not need to be given on the commandline: +export BORG_REPO=ssh://$USER@$HOST/backup +# some helpers and error handling: +info() { printf "\n%s %s\n\n" "$( date )" "$*" >&2; } +trap 'echo $( date ) Backup interrupted >&2; exit 2' INT TERM + +info "Starting backup" + +# Backup the most important directories into an archive named after +# the machine this script is currently running on: + +borg create \ + --verbose \ + --filter AME \ + --list \ + --stats \ + --show-rc \ + --compression lzma,9 \ + --exclude-caches \ + --exclude 'sh:**/.git' \ + \ + ::$NAME'-{now}' \ + $SRC_FOLDER + +backup_exit=$? + +info "Pruning repository" + +borg prune \ + --list \ + --glob-archives $NAME'-*' \ + --show-rc \ + --keep-within 1w + +prune_exit=$? + +# actually free repo disk space by compacting segments + +info "Compacting repository" + +borg compact + +compact_exit=$? + +# use highest exit code as global exit code +global_exit=$(( backup_exit > prune_exit ? backup_exit : prune_exit )) +global_exit=$(( compact_exit > global_exit ? compact_exit : global_exit )) + +if [ ${global_exit} -eq 0 ]; then + info "Backup, Prune, and Compact finished successfully" +elif [ ${global_exit} -eq 1 ]; then + info "Backup, Prune, and/or Compact finished with warnings" +else + info "Backup, Prune, and/or Compact finished with errors" +fi + +exit ${global_exit} diff --git a/docker/gitea/start.sh b/docker/gitea/start.sh new file mode 100755 index 0000000..248e0f2 --- /dev/null +++ b/docker/gitea/start.sh @@ -0,0 +1,20 @@ +#!/bin/sh + +IMAGE_NAME=gitea/gitea +IMAGE_TAG=latest +CONTAINER_NAME=gitea + +HOST_DIR=/srv/$CONTAINER_NAME +SLAVE_DIR=/data + +docker run \ + --detach \ + --restart always \ + --hostname git \ + --publish 8002:3000 \ + --publish 2222:22 \ + --name $CONTAINER_NAME \ + --volume $HOST_DIR:$SLAVE_DIR \ + $IMAGE_NAME:$IMAGE_TAG + + diff --git a/docker/grafana/start.sh b/docker/grafana/start.sh new file mode 100755 index 0000000..e5fb78b --- /dev/null +++ b/docker/grafana/start.sh @@ -0,0 +1,10 @@ +#!/bin/sh + +docker run \ + --detach \ + --user root \ + --volume "/srv/grafana:/var/lib/grafana" \ + --publish 3000:3000 \ + --name grafana \ + --restart unless-stopped \ + grafana/grafana-oss diff --git a/docker/influx/start.sh b/docker/influx/start.sh new file mode 100755 index 0000000..ebb0769 --- /dev/null +++ b/docker/influx/start.sh @@ -0,0 +1,9 @@ +#!/bin/sh + +docker run \ + --detach \ + --publish 8086:8086 \ + --volume /srv/influx:/var/lib/influxdb2 \ + --restart unless-stopped \ + --name influx \ + influxdb:latest diff --git a/docker/nextcloud/docker-compose.yml b/docker/nextcloud/docker-compose.yml new file mode 100644 index 0000000..4fa90eb --- /dev/null +++ b/docker/nextcloud/docker-compose.yml @@ -0,0 +1,27 @@ +services: + nextcloud: + image: nextcloud + ports: + - "8008:80" + volumes: + - /srv/nextcloud/:/var/www/html + restart: always + environment: + - POSTGRES_HOST=nextcloud_db_1 # service name for postgres as assigned by Docker + - POSTGRES_DB=nextcloud_db + - POSTGRES_USER=postgres # will access postgres over 5432 + - POSTGRES_PASSWORD=ncdbpwd + - PHP_MEMORY_LIMIT=1024M + - PHP_UPLOAD_LIMIT=1024M + depends_on: + - db + + db: + image: postgres:13 + restart: always + volumes: + - /srv/postgres-data:/var/lib/postgresql/data + environment: + - POSTGRES_DB=nextcloud_db + - POSTGRES_USER=postgres + - POSTGRES_PASSWORD=ncdbpwd diff --git a/update.sh b/update.sh new file mode 100755 index 0000000..282d7f6 --- /dev/null +++ b/update.sh @@ -0,0 +1,49 @@ +#!/bin/sh + +# wake up backup machine +./wake_probook.sh 20 +if [ $? -ne 0 ]; then + echo "Unable to wake up backup machine" + exit 1 +fi + +# stop web server to avoid access +echo "Stopping web server" +systemctl stop nginx + +# nextcloud +echo "Backup nextcloud..." +docker-compose -f docker/nextcloud/docker-compose.yml down --rmi all +./borg.sh Nextcloud /srv/nextcloud +./borg.sh Postgres /srv/postgres-data +docker-compose -f docker/nextcloud/docker-compose.yml up -d + +# gitea +echo "Backup gitea..." +docker stop gitea +docker rm gitea +docker rmi gitea/gitea:latest +./borg.sh Gitea /srv/gitea + +# influx/grafana +echo "Backup influx/grafana..." +docker stop influx +docker rm influx +docker stop grafana +docker rm grafana +docker rmi influxdb grafana/grafana-oss +./borg.sh Influx /srv/influx +./borg.sh Grafana /srv/grafana + +# activitycollect +echo "Backup activitycollect..." +docker stop activitycollect +./borg.sh Activitycollect /srv/activitycollect +docker start activitycollect + +# re-start nginx +echo "Starting nginx" +systemctl start nginx + +# shutdown backup machine +ssh root@probook 'systemctl poweroff' diff --git a/wake_probook.sh b/wake_probook.sh new file mode 100755 index 0000000..5e0884f --- /dev/null +++ b/wake_probook.sh @@ -0,0 +1,36 @@ +#!/bin/sh +host=probook +host_mac=2c:41:38:08:6c:44 +timeout=1 + +# when no count parameter is set use 1 +if [ $# -ne 0 ]; then + timeout=$1 +fi + +echo -n "Checking if $host is already alive... " +ping -c 1 $host >/dev/null 2>&1 +if [ $? -eq 0 ]; then + echo "yes. Done" + exit 0 +fi +echo "no." + +echo -n "Trying to wake up $host ... " + +while [ $timeout -gt 0 ]; do + wol $host_mac >/dev/null 2>&1 + ping -c 1 $host >/dev/null 2>&1 + if [ $? -eq 0 ]; then + echo "success." + exit 0 + fi + ((timeout--)) + echo "no." + echo -n "Re-trying to wake up $host ... " +done + +echo "no." +echo "Unable to wake up $host" +exit 1 +