commit 4dbe8a5394bd5ac58c5eacda3ed0531d43fb3646 Author: Baptiste Bouchereau Date: Sat Mar 2 22:01:29 2019 +1300 Initial commit diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml new file mode 100644 index 0000000..c016fd9 --- /dev/null +++ b/.gitlab-ci.yml @@ -0,0 +1,32 @@ +image: docker:latest + +services: + - docker:dind + +stages: + - build + - push + +before_script: + - docker login -u gitlab-ci-token -p $CI_JOB_TOKEN $CI_REGISTRY + +build-borgbackup-cron: + stage: build + script: + - docker build --pull -t $CI_REGISTRY_IMAGE/borgbackup-cron . + +push-borgbackup-cron-latest: + stage: push + script: + - docker build --pull -t $CI_REGISTRY_IMAGE/borgbackup-cron:latest . + - docker push $CI_REGISTRY_IMAGE/borgbackup-cron:latest + only: + - master + +push-borgbackup-cron-tagged: + stage: push + script: + - docker build --pull -t $CI_REGISTRY_IMAGE/borgbackup-cron:$CI_COMMIT_TAG . + - docker push $CI_REGISTRY_IMAGE/borgbackup-cron:$CI_COMMIT_TAG + only: + - tags diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..5fe0717 --- /dev/null +++ b/Dockerfile @@ -0,0 +1,27 @@ +FROM ovski/ansible:v2.7.8 + +# Install borg +RUN apt-get install -y \ + python3 \ + python3-dev \ + python3-pip \ + python-virtualenv \ + libssl-dev openssl \ + libacl1-dev libacl1 \ + build-essential \ + borgbackup + +# Install cron +RUN apt-get install -y cron + +COPY entrypoint.sh /var/entrypoint.sh +RUN chmod +x /var/entrypoint.sh + +COPY backup_script.sh /var/backup_script.sh +RUN chmod +x /var/backup_script.sh + +COPY borgbackup_cron /etc/cron.d/borgbackup_cron +RUN chmod +x /etc/cron.d/borgbackup_cron +RUN crontab /etc/cron.d/borgbackup_cron + +CMD [ "/var/entrypoint.sh" ] diff --git a/README.md b/README.md new file mode 100644 index 0000000..bee93fc --- /dev/null +++ b/README.md @@ -0,0 +1,40 @@ +Borg backup cron +================= + +A docker image to backup periodically a folder using borg + +Build +----- + +``` +git clone git@gitlab.com:ovski-projects/docker-images/borgbackup-cron.git +cd borgbackup-cron +docker build -t ovski/borgbackup-cron:latest . +``` + +Usage +----- + +docker run \ + -d \ + -v /path/to/folder_to_backup:/var/folder_to_backup \ + -v /path/to/backup_user_private_key:/var/run/backup_user_private_key \ + -e SSH_KNOWN_HOSTS=my-server.com,27.189.111.145 \ + -e SSH_CONNECTION=backup_user@my-server.com \ + -e PRIVATE_KEY_PATH=/var/run/backup_user_private_key \ + -e BORG_REPO_PATH=/home/backup_user/borg_repositories \ + -e BORG_REPO_NAME=folder_to_backup \ + -e BORG_PASSPHRASE=youyouthatsnotgood \ + -e LOCAL_FOLDER=/var/folder_to_backup \ + -e GITLAB_USER=gitlab+deploy-token-99999 \ + -e GITLAB_PASSWORD=keyhereverysecret \ + ovski/borgbackup-cron + +You can also use secrets in a stack to store sensitive information. +Instead of specifiying environment variables, create the following secrets in /var/secrets (default location): + +``` +/run/secrets/borg_passphrase +/run/secrets/gitlab_user +/run/secrets/gitlab_password +``` diff --git a/backup_script.sh b/backup_script.sh new file mode 100644 index 0000000..960e424 --- /dev/null +++ b/backup_script.sh @@ -0,0 +1,9 @@ +#!/bin/bash + +ansible-playbook /var/ansible/playbooks/borg-backup/main.yml \ + -e ssh_connection=$SSH_CONNECTION \ + -e private_key_path=$PRIVATE_KEY_PATH \ + -e borg_repo_path=$BORG_REPO_PATH \ + -e borg_repo_name=$BORG_REPO_NAME \ + -e borg_passphrase=$BORG_PASSPHRASE \ + -e local_folder=$LOCAL_FOLDER diff --git a/borgbackup_cron b/borgbackup_cron new file mode 100644 index 0000000..1dc75bb --- /dev/null +++ b/borgbackup_cron @@ -0,0 +1,13 @@ +PATH=/usr/bin:/bin:/usr/sbin:/sbin:/usr/local/bin +SHELL=/bin/bash +BASH_ENV=/container.env + +# minutes hours day-of-month month day-0f-week command + +# Every 5 minutes +*/5 * * * * echo "=== I'm alive ===" > /proc/1/fd/1 2>/proc/1/fd/2 + +# Backup every day at 1AM +0 1 * * * /var/backup_script.sh > /proc/1/fd/1 2>/proc/1/fd/2 + +# Don't remove the empty line at the end of this file. It is required to run the cron job diff --git a/entrypoint.sh b/entrypoint.sh new file mode 100644 index 0000000..9998b5b --- /dev/null +++ b/entrypoint.sh @@ -0,0 +1,42 @@ +#!/bin/bash + +# Add known hosts +if [[ -n "$SSH_KNOWN_HOSTS" ]]; then + echo "Adding domains and ips to known hosts" + mkdir -p ~/.ssh + touch ~/.ssh/known_hosts + chmod 644 ~/.ssh/known_hosts + while IFS=' ' read -ra entries; do + for entry in "${entries[@]}"; do + ssh-keyscan -Ht rsa ${entry} >> ~/.ssh/known_hosts + done + done <<< "$SSH_KNOWN_HOSTS" +fi + +# Clone ansible playbooks +if [[ ! -z "$GITLAB_USER" && ! -z "$GITLAB_PASSWORD" ]]; then + echo "Cloning ansible gitlab repository" + git clone https://${GITLAB_USER}:${GITLAB_PASSWORD}@gitlab.com/ovski-projects/infra/ansible.git /var/ansible +elif [[ -f /run/secrets/gitlab_user && -f /run/secrets/gitlab_password ]]; then + GITLAB_USER=$(cat /run/secrets/gitlab_user) + GITLAB_PASSWORD=$(cat /run/secrets/gitlab_password) + git clone https://${GITLAB_USER}:${GITLAB_PASSWORD}@gitlab.com/ovski-projects/infra/ansible.git /var/ansible +else + echo "Gitlab credentials not set. Exiting" + exit 1 +fi + +# Set borg passphrase env variable +if [[ -f /run/secrets/borg_passphrase ]]; then + echo "Setting BORG_PASSPHRASE env variable from secret" + export BORG_PASSPHRASE=$(cat /run/secrets/borg_passphrase) +elif [[ -z "$BORG_PASSPHRASE" ]]; then + echo "BORG_PASSPHRASE env variable not set. Exiting" + exit 1 +fi + +# Make env variables accessible in crontab +declare -p | grep -Ev 'BASHOPTS|BASH_VERSINFO|EUID|PPID|SHELLOPTS|UID' > /container.env + +echo "Run the crontab in the foreground" +cron -f