diff --git a/roles/nextcloud/defaults/main.yml b/roles/nextcloud/defaults/main.yml index 732cb18..4881068 100644 --- a/roles/nextcloud/defaults/main.yml +++ b/roles/nextcloud/defaults/main.yml @@ -18,6 +18,10 @@ nextcloud_redis_password: myredispass nextcloud_db_username: nextcloud nextcloud_db_password: secretnextcloud +# run restic backups +nextcloud_backup_enable: true +nextcloud_backup_cron: 0 30 3 * * * + nextcloud_php_memory_limit: 5G # maximum ram php may use nextcloud_php_upload_limit: 15G # maximum size of (web) uploaded files diff --git a/roles/nextcloud/files/Caddyfile b/roles/nextcloud/files/Caddyfile index a54f3f5..a56ed59 100644 --- a/roles/nextcloud/files/Caddyfile +++ b/roles/nextcloud/files/Caddyfile @@ -10,7 +10,7 @@ header { # enable HSTS - Strict-Transport-Security max-age=31536000; + Strict-Transport-Security max-age=31536000;includeSubDomains;preload; Permissions-Policy interest-cohort=() X-Content-Type-Options nosniff X-Frame-Options SAMEORIGIN @@ -18,11 +18,13 @@ X-XSS-Protection "1; mode=block" X-Permitted-Cross-Domain-Policies none X-Robots-Tag "noindex, nofollow" - -X-Powered-By } + # client support (e.g. os x calendar / contacts) redir /.well-known/carddav /remote.php/dav 301 redir /.well-known/caldav /remote.php/dav 301 + redir /.well-known/webfinger /index.php/.well-known/webfinger 301 + redir /.well-known/nodeinfo /index.php/.well-known/nodeinfo 301 # Uncomment this block if you use the high speed files backend: https://github.com/nextcloud/notify_push #handle_path /push/* { diff --git a/roles/nextcloud/templates/docker-stack.yml.j2 b/roles/nextcloud/templates/docker-stack.yml.j2 index 80f28fa..ff5f6ce 100644 --- a/roles/nextcloud/templates/docker-stack.yml.j2 +++ b/roles/nextcloud/templates/docker-stack.yml.j2 @@ -160,6 +160,24 @@ services: networks: - backend +{% if backup_enable is not undefined and not false and nextcloud_backup_enable is not undefined and not false %} + backup: + image: mazzolino/restic + environment: + - "TZ={{ restic_timezone }}" + # go-cron starts w seconds + - "BACKUP_CRON={{ nextcloud_backup_cron }}" + - "RESTIC_REPOSITORY={{ restic_repo }}" + - "AWS_ACCESS_KEY_ID={{ restic_s3_key }}" + - "AWS_SECRET_ACCESS_KEY={{ restic_s3_secret }}" + - "RESTIC_PASSWORD={{ restic_pass }}" + - "RESTIC_BACKUP_TAGS=nextcloud" + - "RESTIC_BACKUP_SOURCES=/volumes" + volumes: + - db:/volumes/nextcloud_db:ro + - data:/volumes/nextcloud_data:ro +{% endif %} + # metrics: # image: telegraf # hostname: "${HOSTNAME:-vmi352583.contaboserver.net}" diff --git a/roles/restic/README.md b/roles/restic/README.md new file mode 100644 index 0000000..8849990 --- /dev/null +++ b/roles/restic/README.md @@ -0,0 +1,49 @@ +# restic + +Backup maintenance stack. + +Takes care of regularly pruning the backup repository and checking its integrity. +Currently only supports S3 as a backend. + +## Defaults + +```yaml +restic_timezone: US/Chicago +``` + +The timezone to be used for the cronjob. + +```yaml +restic_version: latest +``` + +The docker image version to be used in stack creation. + +```yaml +restic_repo: s3.eu-central-1.wasabisys.com/myrepo +restic_pass: +``` + +The repository url and the restic repository password. +See the restic documentation for more information. + +```yaml +restic_s3_key: +restic_s3_secret: +``` + +The restic S3 credentials, i.e. the `AWS_ACCESS_KEY_ID` and `AWS_SECRET_ACCESS_KEY`. + +```yaml +restic_prune_cron: 0 0 4 * * * +restic_forget_args: --prune --keep-last 14 --keep-daily 2 --keep-weekly 2 +``` + +The default prune and forget cronjob schedule and arguments: Prune the repository every day at 4:00 AM and keep the last 14 snapshots, 2 daily snapshots and 2 weekly snapshots. + +```yaml +restic_check_cron: 0 15 5 * * * +restic_check_args: --read-data-subset=5% +``` + +The default check cronjob schedule and arguments: Check the repository integrity every day at 5:15 AM and in addition to structural checks, read 5 randomly chosen % for a data integrity check. diff --git a/roles/restic/defaults/main.yml b/roles/restic/defaults/main.yml new file mode 100644 index 0000000..48fdbc7 --- /dev/null +++ b/roles/restic/defaults/main.yml @@ -0,0 +1,14 @@ +--- +restic_version: latest + +# restic_repo: s3.eu-central-1.wasabisys.com/myrepo +# restic_pass: +# restic_s3_key: +# restic_s3_secret: +restic_timezone: "{{ server_timezone | default('US/Chicago') }}" + +restic_prune_cron: 0 0 4 * * * +restic_forget_args: --prune --keep-last 14 --keep-daily 2 --keep-weekly 2 + +restic_check_cron: 0 30 4 * * SUN +restic_check_args: --read-data-subset=15% diff --git a/roles/restic/meta/main.yml b/roles/restic/meta/main.yml new file mode 100644 index 0000000..0c765ab --- /dev/null +++ b/roles/restic/meta/main.yml @@ -0,0 +1,10 @@ +--- +galaxy_info: + author: Marty Oehme + description: Installs a restic-based backup maintenance stack. Only supports S3 atm. + license: GPL-3.0-only + min_ansible_version: "2.9" + galaxy_tags: [] + +dependencies: + - docker-swarm diff --git a/roles/restic/tasks/main.yml b/roles/restic/tasks/main.yml new file mode 100644 index 0000000..5bb5027 --- /dev/null +++ b/roles/restic/tasks/main.yml @@ -0,0 +1,11 @@ +--- +- name: Deploy restic to swarm + community.general.docker_stack: + name: "{{ stack_name }}" + state: present + prune: yes + compose: + - "{{ stack_compose }}" + become: true + tags: + - docker-swarm diff --git a/roles/restic/templates/docker-stack.yml.j2 b/roles/restic/templates/docker-stack.yml.j2 new file mode 100644 index 0000000..f64be0a --- /dev/null +++ b/roles/restic/templates/docker-stack.yml.j2 @@ -0,0 +1,30 @@ +services: + prune: + image: "{{ stack_image }}:{{ restic_version }}" + hostname: docker + environment: + - "TZ={{ restic_timezone }}" + - "SKIP_INIT=true" + - "RUN_ON_STARTUP=true" + # go-cron starts w seconds + - "PRUNE_CRON={{ restic_prune_cron }}" + - "RESTIC_FORGET_ARGS={{ restic_forget_args }}" + - "RESTIC_REPOSITORY={{ restic_repo }}" + - "AWS_ACCESS_KEY_ID={{ restic_s3_key }}" + - "AWS_SECRET_ACCESS_KEY={{ restic_s3_secret }}" + - "RESTIC_PASSWORD={{ restic_pass }}" + + check: + image: "{{ stack_image }}:{{ restic_version }}" + hostname: docker + environment: + - "TZ={{ restic_timezone }}" + - "SKIP_INIT=true" + - "RUN_ON_STARTUP=false" + # go-cron starts w seconds + - "CHECK_CRON={{ restic_check_cron }}" + - "RESTIC_CHECK_ARGS={{ restic_check_args }}" + - "RESTIC_REPOSITORY={{ restic_repo }}" + - "AWS_ACCESS_KEY_ID={{ restic_s3_key }}" + - "AWS_SECRET_ACCESS_KEY={{ restic_s3_secret }}" + - "RESTIC_PASSWORD={{ restic_pass }}" diff --git a/roles/restic/vars/main.yml b/roles/restic/vars/main.yml new file mode 100644 index 0000000..8b3dcf5 --- /dev/null +++ b/roles/restic/vars/main.yml @@ -0,0 +1,8 @@ +--- +stack_name: restic + +stack_image: "mazzolino/restic" + +stack_compose: "{{ lookup('template', 'docker-stack.yml.j2') | from_yaml }}" + +backup_enable: true diff --git a/roles/shaarli/defaults/main.yml b/roles/shaarli/defaults/main.yml index a654c5f..45f1bef 100644 --- a/roles/shaarli/defaults/main.yml +++ b/roles/shaarli/defaults/main.yml @@ -7,3 +7,7 @@ shaarli_use_https: true # the subdomain link shaarli will be reachable under subdomain_alias: links + +# should we back up the data? +shaarli_backup_enable: true +shaarli_backup_cron: 0 45 3 * * * diff --git a/roles/shaarli/templates/docker-stack.yml.j2 b/roles/shaarli/templates/docker-stack.yml.j2 index 545d20e..a90157a 100644 --- a/roles/shaarli/templates/docker-stack.yml.j2 +++ b/roles/shaarli/templates/docker-stack.yml.j2 @@ -15,6 +15,23 @@ services: - data:/var/www/shaarli/data - cache:/var/www/shaarli/cache +{% if backup_enable is not undefined and not false and shaarli_backup_enable is not undefined and not false %} + backup: + image: mazzolino/restic + environment: + - "TZ={{ restic_timezone }}" + # go-cron starts w seconds + - "BACKUP_CRON={{ shaarli_backup_cron }}" + - "RESTIC_REPOSITORY={{ restic_repo }}" + - "AWS_ACCESS_KEY_ID={{ restic_s3_key }}" + - "AWS_SECRET_ACCESS_KEY={{ restic_s3_secret }}" + - "RESTIC_PASSWORD={{ restic_pass }}" + - "RESTIC_BACKUP_TAGS=shaarli" + - "RESTIC_BACKUP_SOURCES=/volumes" + volumes: + - data:/volumes/shaarli_data:ro +{% endif %} + volumes: data: cache: diff --git a/site.yml b/site.yml index 892a4e2..19f483d 100644 --- a/site.yml +++ b/site.yml @@ -24,6 +24,12 @@ tags: - caddy + - name: Install restic backup management + import_role: + role: restic + tags: + - restic + - name: Grab caddy container id for all following services import_role: role: caddy_id