Variables, Dockerfile, better syntax, etc.
This commit is contained in:
parent
49ed657084
commit
8317f50a8a
|
@ -0,0 +1,8 @@
|
||||||
|
export RESTIC_SFTP_HOST="user@domain.tld"
|
||||||
|
export RESTIC_PASSWORD_FILE=/run/secrets/restic-password
|
||||||
|
export BACKUP_DEST=/backups
|
||||||
|
|
||||||
|
export SERVER_NAME=domain.tld
|
||||||
|
export DOCKER_CONTEXT=$SERVER_NAME
|
||||||
|
|
||||||
|
#export SERVICES_OVERRIDE="ghost_domain_tld_app ghost_domain_tld_db"
|
|
@ -0,0 +1,14 @@
|
||||||
|
FROM docker:19.03.13-dind
|
||||||
|
|
||||||
|
RUN apk add --upgrade --no-cache \
|
||||||
|
bash \
|
||||||
|
curl \
|
||||||
|
restic
|
||||||
|
|
||||||
|
RUN curl -L https://github.com/stedolan/jq/releases/download/jq-1.6/jq-linux64 --output /usr/bin/jq
|
||||||
|
RUN chmod +x /usr/bin/jq
|
||||||
|
|
||||||
|
COPY backup.sh /usr/bin/backup.sh
|
||||||
|
RUN chmod +x /usr/bin/backup.sh
|
||||||
|
|
||||||
|
ENTRYPOINT ["/usr/bin/backup.sh"]
|
21
README.md
21
README.md
|
@ -2,6 +2,13 @@
|
||||||
|
|
||||||
Automatically backup files from running Docker Swarm services based on labels.
|
Automatically backup files from running Docker Swarm services based on labels.
|
||||||
|
|
||||||
|
## Background
|
||||||
|
|
||||||
|
There are lots of Docker volume backup systems; all of them have one or both of
|
||||||
|
these problems:
|
||||||
|
- You need to define all the volumes to back up in the configuration system
|
||||||
|
- Backups require services to be stopped to take consistent copies
|
||||||
|
|
||||||
## TODO
|
## TODO
|
||||||
|
|
||||||
- [ ] Make a Docker image of this
|
- [ ] Make a Docker image of this
|
||||||
|
@ -13,8 +20,9 @@ Automatically backup files from running Docker Swarm services based on labels.
|
||||||
|
|
||||||
(Haven't done secrets yet, here are two options)
|
(Haven't done secrets yet, here are two options)
|
||||||
|
|
||||||
v1:
|
|
||||||
```
|
```
|
||||||
|
services:
|
||||||
|
db:
|
||||||
deploy:
|
deploy:
|
||||||
labels:
|
labels:
|
||||||
backupbot.backup: "true"
|
backupbot.backup: "true"
|
||||||
|
@ -24,17 +32,6 @@ v1:
|
||||||
backupbot.backup.post-hook: "rm -rf /tmp/dump/dump.db"
|
backupbot.backup.post-hook: "rm -rf /tmp/dump/dump.db"
|
||||||
backupbot.backup.path: "/tmp/dump/"
|
backupbot.backup.path: "/tmp/dump/"
|
||||||
```
|
```
|
||||||
v2:
|
|
||||||
```
|
|
||||||
deploy:
|
|
||||||
labels:
|
|
||||||
backupbot.backup: "true"
|
|
||||||
backupbot.backup.repos: "$some_thing"
|
|
||||||
backupbot.backup.at: "* * * * *"
|
|
||||||
backupbot.backup.post-hook: "rm -rf /tmp/dump/dump.db"
|
|
||||||
backupbot.backup.secrets": "db_root_password",
|
|
||||||
backupbot.backup.pre-hook: 'mysqldump -u root -p"$DB_ROOT_PASSWORD" -f /tmp/dump/dump.db'
|
|
||||||
```
|
|
||||||
|
|
||||||
## Questions:
|
## Questions:
|
||||||
|
|
||||||
|
|
31
backup.sh
31
backup.sh
|
@ -1,15 +1,20 @@
|
||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
|
|
||||||
# FIXME: just for testing
|
server_name="${SERVER_NAME:?SERVER_NAME not set}"
|
||||||
backup_path=backups
|
|
||||||
|
|
||||||
# FIXME: just for testing
|
restic_password_file="${RESTIC_PASSWORD_FILE:?RESTIC_PASSWORD_FILE not set}"
|
||||||
export DOCKER_CONTEXT=demo.coopcloud.tech
|
|
||||||
|
|
||||||
|
restic_sftp_host="${RESTIC_SFTP_HOST:?RESTIC_SFTP_HOST not set}"
|
||||||
|
|
||||||
|
restic_repo="sftp:$restic_sftp_host:/$server_name"
|
||||||
|
|
||||||
|
backup_path="${BACKUP_DEST:?BACKUP_DEST not set}"
|
||||||
|
|
||||||
|
if [ -n "$SERVICES_OVERRIDE" ]; then
|
||||||
|
services=($SERVICES_OVERRIDE)
|
||||||
|
else
|
||||||
mapfile -t services < <(docker service ls --format '{{ .Name }}')
|
mapfile -t services < <(docker service ls --format '{{ .Name }}')
|
||||||
|
fi
|
||||||
# FIXME: just for testing
|
|
||||||
services=( "ghost_demo_app" "ghost_demo_db" )
|
|
||||||
|
|
||||||
for service in "${services[@]}"; do
|
for service in "${services[@]}"; do
|
||||||
echo "service: $service"
|
echo "service: $service"
|
||||||
|
@ -32,7 +37,7 @@ for service in "${services[@]}"; do
|
||||||
if [ "$pre" != "null" ]; then
|
if [ "$pre" != "null" ]; then
|
||||||
# run the precommand
|
# run the precommand
|
||||||
# shellcheck disable=SC2086
|
# shellcheck disable=SC2086
|
||||||
docker exec "$container" $pre
|
docker exec "$container" sh -c "$pre"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# run the backup
|
# run the backup
|
||||||
|
@ -41,10 +46,12 @@ for service in "${services[@]}"; do
|
||||||
if [ "$post" != "null" ]; then
|
if [ "$post" != "null" ]; then
|
||||||
# run the postcommand
|
# run the postcommand
|
||||||
# shellcheck disable=SC2086
|
# shellcheck disable=SC2086
|
||||||
docker exec "$container" $post
|
docker exec "$container" sh -c "$post"
|
||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
restic -p restic-password \
|
|
||||||
backup --quiet -r sftp:u272979@u272979.your-storagebox.de:/demo.coopcloud.tech \
|
|
||||||
--tag coop-cloud "$backup_path"
|
|
||||||
done
|
done
|
||||||
|
|
||||||
|
restic -p "$restic_password_file" \
|
||||||
|
backup --quiet -r "$restic_repo" \
|
||||||
|
-o sftp.command="ssh $restic_sftp_host -s sftp" \
|
||||||
|
--tag coop-cloud "$backup_path"
|
||||||
|
|
|
@ -0,0 +1,30 @@
|
||||||
|
---
|
||||||
|
version: "3.8"
|
||||||
|
services:
|
||||||
|
app:
|
||||||
|
image: thecoopcloud/backup-bot-two:latest
|
||||||
|
volumes:
|
||||||
|
- "/var/run/docker.sock:/var/run/docker.sock"
|
||||||
|
- "backups:/backups"
|
||||||
|
environment:
|
||||||
|
- RESTIC_REPO
|
||||||
|
- RESTIC_PASSWORD_FILE=/run/secrets/restic_password
|
||||||
|
- BACKUP_DEST=/backups
|
||||||
|
- SERVER_NAME
|
||||||
|
secrets:
|
||||||
|
- restic_password
|
||||||
|
|
||||||
|
deploy:
|
||||||
|
mode: replicated
|
||||||
|
replicas: 0
|
||||||
|
labels:
|
||||||
|
- "swarm.cronjob.enable=true"
|
||||||
|
# Note(3wc): every minute, testing
|
||||||
|
- "swarm.cronjob.schedule=*/5 * * * *"
|
||||||
|
# - "swarm.cronjob.schedule=0 9 * * 1-5" # office hours
|
||||||
|
- coop-cloud.${STACK_NAME}.app.version=24.98.9-slim-d3db1c25
|
||||||
|
restart_policy:
|
||||||
|
condition: none
|
||||||
|
|
||||||
|
volumes:
|
||||||
|
backups:
|
Loading…
Reference in New Issue