From 9b3e1af9d6d43f62a7cd909cbf62251710f5d984 Mon Sep 17 00:00:00 2001 From: Jimmy Date: Sun, 11 Jun 2023 05:03:27 +1200 Subject: [PATCH] Initial commit --- .env.sample | 32 ++++++++++++++ .gitignore | 2 + Dockerfile | 21 +++++++++ README.md | 32 ++++++++++++++ backup.sh | 105 ++++++++++++++++++++++++++++++++++++++++++++ docker-compose.yaml | 21 +++++++++ entry.sh | 15 +++++++ 7 files changed, 228 insertions(+) create mode 100644 .env.sample create mode 100644 .gitignore create mode 100644 Dockerfile create mode 100644 README.md create mode 100755 backup.sh create mode 100644 docker-compose.yaml create mode 100755 entry.sh diff --git a/.env.sample b/.env.sample new file mode 100644 index 0000000..cb8b08a --- /dev/null +++ b/.env.sample @@ -0,0 +1,32 @@ +# Description: Sample .env file for docker-compose +# Copy this file to .env and edit it to your needs + +# ssh://host:port/path/to/repo +BORG_REPO= + +# remote url +SERVER= + +# borg passphrase +BORG_PASSPHRASE= + +# prune settings +MINUTELY=60 +HOURLY=24 +DAILY=7 +WEEKLY=4 + +# cron format: minute hour day month day_of_week +# cron example: every 5 minutes: SCHEDULE='*/5 * * * *' +# cron at 3am and 12am: SCHEDULE='0 3,12 * * +SCHEDULE='* * * * *' + +# folder to backup +SRC= +# path to ssh key +SSH_KEY= +# backup name +HOSTNAME= + +# don't change this +COMMAND='/backup.sh backup' \ No newline at end of file diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..f19bec4 --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +.env +restore \ No newline at end of file diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..4024174 --- /dev/null +++ b/Dockerfile @@ -0,0 +1,21 @@ +FROM debian:latest + +ENV COMMAND="/usr/bin/backup backup" + +COPY --from=docker:dind /usr/local/bin/docker /usr/local/bin/ + +RUN apt-get update && apt-get install -yq python3 python3-pip trickle wget cron openssh-client info redis-tools mariadb-client postgresql-client iputils-ping borgbackup + +RUN wget https://github.com/borgbackup/borg/releases/download/1.2.3/borg-linuxnew64 -O /usr/local/bin/borg &&\ + chown root:root /usr/local/bin/borg && \ + chmod 755 /usr/local/bin/borg + +RUN mkdir /root/.ssh && ln -s /run/secrets/ssh_key /root/.ssh/id_rsa + +COPY entry.sh /entry.sh + +COPY backup.sh /usr/bin/backup + +VOLUME [ "/src", "/dest" ] + +ENTRYPOINT [ "/entry.sh" ] \ No newline at end of file diff --git a/README.md b/README.md new file mode 100644 index 0000000..0790217 --- /dev/null +++ b/README.md @@ -0,0 +1,32 @@ +# Backup +Borg based backups + +## Usage + +```cp .env.sample .env``` + +### Init Repo + +```docker-compose run --rm backup init``` + +### Run on Schedule + +```docker-compose up -d``` + +### Create a Backup + +```docker-compose run --rm backup backup``` + +### List Backups + +```docker-compose run --rm backup list``` + +### Delete Backup + +```docker-compose run --rm backup delete [backup]``` + +### Restore Backup + +```docker-compose run --rm restore [backup]``` + +The restored backup can be found at ./restore diff --git a/backup.sh b/backup.sh new file mode 100755 index 0000000..26cd62f --- /dev/null +++ b/backup.sh @@ -0,0 +1,105 @@ +#!/bin/bash + +# Create a backup, prune old backups, compact the repository, and list the contents +backup() { + #check PRE_COMMAND exists + if [[ -n $PRE_COMMAND ]]; then + echo "Running pre-command" + eval $PRE_COMMAND + fi + create + prune + compact + list + #check POST_COMMAND exists + if [[ -n $POST_COMMAND ]]; then + echo "Running post-command" + eval $POST_COMMAND + fi +} + +# Initialize the repository +init() { + echo "Initializing repository" + /usr/local/bin/borg init --encryption=repokey $BORG_REPO +} + +# Create a backup +create() { + echo "Creating backup" + /usr/local/bin/borg create --compression zstd,1 $BORG_REPO::'{hostname}-{now}' /src +} + +# List the contents of the repository +list() { + echo "Listing repository" + /usr/local/bin/borg list $BORG_REPO +} + +PRUNE="" + +# Clean up old backups +prune() { + echo "Pruning repository" + if [[ -n $MINUTELY ]]; then + PRUNE="--keep-minutely ${MINUTELY}" + fi + if [[ -n $HOURLY ]]; then + PRUNE="${PRUNE} --keep-hourly ${HOURLY}" + fi + if [[ -n $DAILY ]]; then + PRUNE="${PRUNE} --keep-daily ${DAILY}" + fi + if [[ -n $WEEKLY ]]; then + PRUNE="${PRUNE} --keep-weekly ${WEEKLY}" + fi + if [[ -n $MONTHLY ]]; then + PRUNE="${PRUNE} --keep-monthly ${MONTHLY}" + fi + /usr/local/bin/borg prune $PRUNE $BORG_REPO +} + +# Compact the repository +compact() { + echo "Compacting repository" + /usr/local/bin/borg compact $BORG_REPO +} + +delete() { + echo "Deleting repository" + /usr/local/bin/borg delete $BORG_REPO $2 +} + +restore() { + echo "Restoring backup" + echo $2 + #Restore dir + cd $RESTORE_PATH + /usr/local/bin/borg -v extract ${BORG_REPO}::$BACKUP +} + +if [[ $1 == "backup" ]]; then + backup +elif [[ $1 == "init" ]]; then + init +elif [[ $1 == "create" ]]; then + create +elif [[ $1 == "list" ]]; then + list +elif [[ $1 == "prune" ]]; then + prune +elif [[ $1 == "compact" ]]; then + compact +elif [[ $1 == "delete" ]]; then + delete +elif [[ $1 == "restore" ]]; then + BACKUP=$2 + RESTORE_PATH=$3 + restore +elif [[ $1 == "bash" ]]; then + bash +elif [[ $1 == "server" ]]; then + /usr/local/bin/borg serve --restrict-to-path /data +else + echo "Invalid command" +fi diff --git a/docker-compose.yaml b/docker-compose.yaml new file mode 100644 index 0000000..9bca9ca --- /dev/null +++ b/docker-compose.yaml @@ -0,0 +1,21 @@ +version: '3.9' + +services: + backup: + image: backup + hostname: ${HOSTNAME} + build: ./ + env_file: + - .env + ports: + - 24:22 + volumes: + - ${SRC} + - ./restore:/restore + - /var/run/docker.sock:/var/run/docker.sock + secrets: + - ssh_key + +secrets: + ssh_key: + file: ${SSH_KEY} diff --git a/entry.sh b/entry.sh new file mode 100755 index 0000000..3e5c008 --- /dev/null +++ b/entry.sh @@ -0,0 +1,15 @@ +#!/bin/bash + +echo $@ + +echo "Host ${SERVER}\n\tStrictHostKeyChecking no\n" >> /root/.ssh/config + +if [[ -z $@ ]]; then + crontab -l ; echo "${SCHEDULE} ${COMMAND} > /proc/1/fd/1 2> /proc/1/fd/2" | crontab + printenv | grep -v "no_proxy" >> /etc/environment + echo Starting Cron + cron -f + exit 0 +fi + +/usr/bin/backup $@