Compare commits
16 commits
06940925a9
...
412054e3cd
| Author | SHA1 | Date | |
|---|---|---|---|
| 412054e3cd | |||
| 945868feff | |||
| 64b85c0c40 | |||
| 363ce9ae6f | |||
| 1fd72a05a6 | |||
| f1be696479 | |||
| 9cf1a5e571 | |||
| af5b647daf | |||
| cd842ea4b5 | |||
| b81328d400 | |||
| e13d85990c | |||
| 065fd4562b | |||
| fab6f5ff7c | |||
| 003cf64a77 | |||
| 86d49a756b | |||
| 93876315ca |
28 changed files with 345 additions and 207 deletions
|
|
@ -1,33 +1,46 @@
|
||||||
$ANSIBLE_VAULT;1.1;AES256
|
$ANSIBLE_VAULT;1.1;AES256
|
||||||
61653738666234666537383737636631323931396632353236366639323833363134313066613962
|
66623361613033616239323361396635633932346566663666346466613132303332663465383037
|
||||||
3730306266353834303135653939323561666131333539380a333039663466393061343736653935
|
3334373161356131653039326630666238303863663034360a633865303562663162303530656436
|
||||||
38613532346132303730363835373165326361373561666565316332623964316265306131663332
|
36346162613333346133363533343731313965663731336130643333633832663161653437393663
|
||||||
3832373861666138330a646631346262666233383938366234373335383064353662326461656430
|
3936643262306639370a323431343661316564393165386634666635633337356134373862326431
|
||||||
35626334356566613731333639663130306133353439666234636137636265313662393730626232
|
34633134643062643837316133616138623736306330316538623632633038393038316365316433
|
||||||
37633430663438666461353735656461623165316134346130663963356464656436313966613739
|
30383363356633613833373738653338376335306361636265303232353838393866353830363434
|
||||||
35373763633936336565666261353631366531323430663461376338373265393235313932363733
|
37353263353734623161333334316433303061643162363033333466326236373761366636343437
|
||||||
66323634656539303732303338376264353935316538373465633462386466383662626534623365
|
35343765303462303231373531616362656634313837383631346263333962366634306530353036
|
||||||
38363362653535386130366462393365393731313034316431373039393331396231663365616435
|
65363033346661323766613961343832323536313339306331626338643336643433333039633666
|
||||||
31373632633264383266623733613530333134643730396336373461633739383436623736613638
|
63336633386531633632346337393435613338306338363636316138353233366334326435396466
|
||||||
39303163373234313534323562643836636337323266366538323932656563376163376162306165
|
37363162636539313831323038383535613062373034346437623337393764663133623436356462
|
||||||
31356165343739373237363734393230356236363339653564326537313336663036313437646636
|
33626361343136376136623964363638303138323330306366353963623962313936666261323334
|
||||||
35313336396361353365323763643861656561633235383732376236333232363565376365386232
|
61393665313164646165316666333663613163386631643262663233666636386566363565626430
|
||||||
32353737373239396436316538323661303164373765343936643736663035323237663935643834
|
35633664643438316263663035326636313532333735396537646266373539373063396532323532
|
||||||
39333238666162363366633938333231313966613430303236636634316136373433323536613833
|
63653262333430663065653838336636616137346538393431306531323234376631616331613437
|
||||||
61386434636464633662383736323630326630313561356335306663333864643462366335643430
|
65346332383438336137363965643438306564656538316331643566303932353336303931333936
|
||||||
34396331633935656632323062613433386234386535613337313561353037356633376664333634
|
31306362343464316263316638613831626539323033313031656462373936303534366438383632
|
||||||
62303063636135343737323331623736303636643735613337633530666134333266323934376631
|
33376562643836303466663437353731343833636630303636376266393866616532636537326130
|
||||||
62386535323834323435373362333662613637383065346335373465343765663836626434666463
|
32633964396132656135376262316563396338336132313436313533616237656335386162363837
|
||||||
39623162313438346239393261613738376435636539623663646461396330326661343633353531
|
61666134613830346361666266633538653861326263666565363738383032656536383637666363
|
||||||
66643362326464376437643732366466633332323837323433343165313735653331346431656136
|
66323135336261376330346633373538383338613765356238323666333266333365646365343563
|
||||||
32376165666437373435646566373036313639316165353639626435333330626530373662333031
|
33363162633333353234353838623864653862383431396237623065303232343034333735333064
|
||||||
37656463333231356465383039336237626235613331376639656665303431353131336436653839
|
34636261333465666433363764373934313139306631616234626365306531303232336163363466
|
||||||
32383031376134643236333231323863633933376238613462623034663262316339353061343635
|
36646666336466663034386634616564626366653963623436343630343263306164313231326166
|
||||||
36336338323331343866643836666530616639313933306536343631303635383862363633373562
|
31326235346363373664353665666436653532333864303864336535653365623465333764653465
|
||||||
65663930306461316363376364663935663566393335396130626436316262643730393133363837
|
66303037303839336164373062613836653732393964323634306438656531613364396132353965
|
||||||
63343334613966343466646366303137663965633639653262316630626436346461643533393135
|
38353766386461663161636139326361663461346262626564326335626339346635356139336238
|
||||||
31303630616662623237313331356263613535323739616162393165336163346161303836653638
|
64373161346363653661666661323732643236303561356164396136343235613762336264366136
|
||||||
30386636663230613731383165333462363033333734326662373961383236386631643139373934
|
65333938633433303365646665346263636262303062626634336564616164626563353665396331
|
||||||
38353732393265656162633739623061333833353138303664633463643234396338643736353132
|
32636164393863336237336331343836373564313935393661646538656539326333656439623363
|
||||||
32313763656165643963373236346364636534333964383131373839616435356631386463646437
|
30653538346661383061363263326430323730636234346365653835346466666439393466303033
|
||||||
39336237356337383930
|
64343133326664356432326631363234356235313035613134306436613364633836633032326332
|
||||||
|
61323861386333653130386637323034336262396433653730323863353230393461316663613339
|
||||||
|
37333334336630653037333366666561363332343533323966346536363237373337346439656533
|
||||||
|
30633239346463373734666330303934316438663666366435613362336661623530333034616165
|
||||||
|
33363336323539383565396337663232393835383734613064393331666135366266633861366333
|
||||||
|
63653466356361343732303864373535366433313130303230323334376561363539336638363930
|
||||||
|
61353666393366306636333437313736386165303535353534326433326136396637613236626634
|
||||||
|
66376239376639393662616161623461643634633930633364333130366136343066376132633934
|
||||||
|
66346165353837613837306231383361326236373132353239356164626264366437316639616263
|
||||||
|
31623066356231323138303339356138303939343631636337353137663137356562353333376636
|
||||||
|
38313066313431386633316339303835363135633434343663636338636365306430643436383430
|
||||||
|
66623666663063353439303433386538623762626563323863396335336461646130353466626230
|
||||||
|
62393063393936393661636235663730623834626432363563353536353339643135336464323936
|
||||||
|
3733
|
||||||
|
|
|
||||||
|
|
@ -54,3 +54,8 @@
|
||||||
ansible.builtin.import_role:
|
ansible.builtin.import_role:
|
||||||
name: grocy
|
name: grocy
|
||||||
tags: grocy
|
tags: grocy
|
||||||
|
|
||||||
|
- name: Set up Restic stack
|
||||||
|
ansible.builtin.import_role:
|
||||||
|
name: restic
|
||||||
|
tags: restic
|
||||||
|
|
|
||||||
|
|
@ -20,6 +20,9 @@ arrstack_puid: "{{ puid | default(1000) }}"
|
||||||
arrstack_pgid: "{{ pgid | default(100) }}"
|
arrstack_pgid: "{{ pgid | default(100) }}"
|
||||||
arrstack_umask_set: "{{ umask_set | default('022') }}"
|
arrstack_umask_set: "{{ umask_set | default('022') }}"
|
||||||
|
|
||||||
|
arrstack_restic_enable: true
|
||||||
|
arrstack_restic_cron: 0 30 2 * * *
|
||||||
|
|
||||||
arrstack_env_dir: /opt/arrstack
|
arrstack_env_dir: /opt/arrstack
|
||||||
arrstack_serve_dir: /srv
|
arrstack_serve_dir: /srv
|
||||||
arrstack_serve_dir_create: true
|
arrstack_serve_dir_create: true
|
||||||
|
|
@ -1,171 +0,0 @@
|
||||||
services:
|
|
||||||
sonarr:
|
|
||||||
container_name: sonarr
|
|
||||||
image: lscr.io/linuxserver/sonarr:latest
|
|
||||||
ports:
|
|
||||||
- 8989:8989
|
|
||||||
environment:
|
|
||||||
- PUID=${PUID}
|
|
||||||
- PGID=${PGID}
|
|
||||||
- UMASK_SET=022
|
|
||||||
- TZ=${TZ}
|
|
||||||
volumes:
|
|
||||||
- "./config/sonarr:/config"
|
|
||||||
- "CHANGE_TO_COMPOSE_DATA_PATH:/data"
|
|
||||||
restart: unless-stopped
|
|
||||||
radarr:
|
|
||||||
container_name: radarr
|
|
||||||
image: lscr.io/linuxserver/radarr:latest
|
|
||||||
ports:
|
|
||||||
- 7878:7878
|
|
||||||
environment:
|
|
||||||
- PUID=${PUID}
|
|
||||||
- PGID=${PGID}
|
|
||||||
- UMASK_SET=022
|
|
||||||
- TZ=${TZ}
|
|
||||||
volumes:
|
|
||||||
- "./config/radarr:/config"
|
|
||||||
- "CHANGE_TO_COMPOSE_DATA_PATH:/data"
|
|
||||||
restart: unless-stopped
|
|
||||||
lidarr:
|
|
||||||
container_name: lidarr
|
|
||||||
image: lscr.io/linuxserver/lidarr:latest
|
|
||||||
ports:
|
|
||||||
- 8686:8686
|
|
||||||
environment:
|
|
||||||
- PUID=${PUID}
|
|
||||||
- PGID=${PGID}
|
|
||||||
- UMASK_SET=022
|
|
||||||
- TZ=${TZ}
|
|
||||||
- DOCKER_MODS=linuxserver/mods:universal-docker
|
|
||||||
volumes:
|
|
||||||
- "./config/lidarr:/config"
|
|
||||||
- "CHANGE_TO_COMPOSE_DATA_PATH:/data"
|
|
||||||
- "/var/run/docker.sock:/var/run/docker.sock:ro"
|
|
||||||
restart: unless-stopped
|
|
||||||
readarr:
|
|
||||||
container_name: readarr
|
|
||||||
image: lscr.io/linuxserver/readarr:develop
|
|
||||||
ports:
|
|
||||||
- 8787:8787
|
|
||||||
environment:
|
|
||||||
- PUID=${PUID}
|
|
||||||
- PGID=${PGID}
|
|
||||||
- UMASK_SET=022
|
|
||||||
- TZ=${TZ}
|
|
||||||
volumes:
|
|
||||||
- "./config/readarr:/config"
|
|
||||||
- "CHANGE_TO_COMPOSE_DATA_PATH:/data"
|
|
||||||
restart: unless-stopped
|
|
||||||
prowlarr:
|
|
||||||
container_name: prowlarr
|
|
||||||
image: lscr.io/linuxserver/prowlarr:develop
|
|
||||||
environment:
|
|
||||||
- PUID=${PUID}
|
|
||||||
- PGID=${PGID}
|
|
||||||
- UMASK_SET=022
|
|
||||||
- TZ=${TZ}
|
|
||||||
volumes:
|
|
||||||
- "./config/prowlarr:/config"
|
|
||||||
ports:
|
|
||||||
- 9696:9696
|
|
||||||
restart: unless-stopped
|
|
||||||
sabnzbd:
|
|
||||||
container_name: sabnzbd
|
|
||||||
image: lscr.io/linuxserver/sabnzbd:latest
|
|
||||||
environment:
|
|
||||||
- PUID=${PUID}
|
|
||||||
- PGID=${PGID}
|
|
||||||
- TZ=${TZ}
|
|
||||||
volumes:
|
|
||||||
- "./config/sabnzbd:/config"
|
|
||||||
- "CHANGE_TO_COMPOSE_DATA_PATH/usenet:/data/usenet:rw"
|
|
||||||
ports:
|
|
||||||
- 8080:8080
|
|
||||||
restart: unless-stopped
|
|
||||||
pia-qbittorrent:
|
|
||||||
image: j4ym0/pia-qbittorrent
|
|
||||||
container_name: pia-qbittorrent
|
|
||||||
cap_add:
|
|
||||||
- NET_ADMIN
|
|
||||||
environment:
|
|
||||||
- UID=${PUID}
|
|
||||||
- GID=${PGID}
|
|
||||||
- TZ=${TZ}
|
|
||||||
- REGION=Netherlands
|
|
||||||
- USER=${PIA_USER}
|
|
||||||
- PASSWORD=${PIA_PASS}
|
|
||||||
volumes:
|
|
||||||
- "./config/piaqbit:/config"
|
|
||||||
- "CHANGE_TO_COMPOSE_DATA_PATH/torrent:/downloads:rw"
|
|
||||||
ports:
|
|
||||||
- "8888:8888"
|
|
||||||
restart: unless-stopped
|
|
||||||
jellyfin:
|
|
||||||
image: lscr.io/linuxserver/jellyfin:latest
|
|
||||||
container_name: jellyfin
|
|
||||||
environment:
|
|
||||||
- PUID={$PUID}
|
|
||||||
- PGID={$PGID}
|
|
||||||
- TZ=${TZ}
|
|
||||||
#- JELLYFIN_PublishedServerUrl=192.168.0.5 #optional
|
|
||||||
volumes:
|
|
||||||
- ".config/jellyfin:/config"
|
|
||||||
- "CHANGE_TO_COMPOSE_DATA_PATH/media:/data"
|
|
||||||
ports:
|
|
||||||
- 8096:8096
|
|
||||||
- 7359:7359/udp #optional - network discovery
|
|
||||||
- 1900:1900/udp #optional - dlna discovery
|
|
||||||
restart: unless-stopped
|
|
||||||
audiobookshelf:
|
|
||||||
container_name: audiobookshelf
|
|
||||||
image: ghcr.io/advplyr/audiobookshelf:latest
|
|
||||||
environment:
|
|
||||||
- PUID=${PUID}
|
|
||||||
- PGID=${PGID}
|
|
||||||
- UMASK_SET=022
|
|
||||||
- TZ=${TZ}
|
|
||||||
ports:
|
|
||||||
- 13378:80
|
|
||||||
volumes:
|
|
||||||
- "CHANGE_TO_COMPOSE_DATA_PATH/media/audio/books:/audiobooks"
|
|
||||||
- "CHANGE_TO_COMPOSE_DATA_PATH/media/audio/podcasts:/podcasts"
|
|
||||||
- ".config/audiobookshelf:/config"
|
|
||||||
- ".metadata/audiobookshelf:/metadata"
|
|
||||||
restart: unless-stopped
|
|
||||||
jellyseerr:
|
|
||||||
image: fallenbagel/jellyseerr:latest
|
|
||||||
container_name: jellyseerr
|
|
||||||
environment:
|
|
||||||
- TZ=${TZ}
|
|
||||||
ports:
|
|
||||||
- 5055:5055
|
|
||||||
volumes:
|
|
||||||
- "./config/jellyseerr:/app/config"
|
|
||||||
restart: unless-stopped
|
|
||||||
beets:
|
|
||||||
image: lscr.io/linuxserver/beets:latest
|
|
||||||
container_name: beets
|
|
||||||
environment:
|
|
||||||
- PUID=${PUID}
|
|
||||||
- PGID=${PGID}
|
|
||||||
- TZ=${TZ}
|
|
||||||
volumes:
|
|
||||||
- "./config/beets:/config"
|
|
||||||
- "CHANGE_TO_COMPOSE_DATA_PATH/media/audio/music:/music"
|
|
||||||
- "CHANGE_TO_COMPOSE_DATA_PATH/media/audio/music-unsorted:/downloads"
|
|
||||||
- "CHANGE_TO_COMPOSE_DATA_PATH:/data"
|
|
||||||
ports:
|
|
||||||
- 8337:8337
|
|
||||||
restart: unless-stopped
|
|
||||||
homarr:
|
|
||||||
image: ghcr.io/ajnart/homarr:latest
|
|
||||||
container_name: homarr
|
|
||||||
volumes:
|
|
||||||
- /var/run/docker.sock:/var/run/docker.sock # Optional, only if you want docker integration
|
|
||||||
- ./config/homarr/configs:/app/data/configs
|
|
||||||
- ./config/homarr/icons:/app/public/icons
|
|
||||||
- ./config/homarr/data:/data
|
|
||||||
ports:
|
|
||||||
- '80:7575'
|
|
||||||
restart: unless-stopped
|
|
||||||
|
|
@ -290,6 +290,26 @@ services:
|
||||||
caddy: "{{ arrstack_gonic_subdomain }}"
|
caddy: "{{ arrstack_gonic_subdomain }}"
|
||||||
caddy.reverse_proxy: "{{ '{{' }}upstreams 80{{ '}}'}}"
|
caddy.reverse_proxy: "{{ '{{' }}upstreams 80{{ '}}'}}"
|
||||||
|
|
||||||
|
{% if restic_enable is not undefined and not false and arrstack_restic_enable is not undefined and not false %}
|
||||||
|
backup:
|
||||||
|
image: mazzolino/restic
|
||||||
|
hostname: "{{ ansible_hostname }}"
|
||||||
|
environment:
|
||||||
|
TZ: "{{ restic_tz }}"
|
||||||
|
BACKUP_CRON: "{{ arrstack_restic_cron }}"
|
||||||
|
RESTIC_REPOSITORY: "{{ restic_repo }}"
|
||||||
|
RESTIC_PASSWORD: "{{ restic_pass }}"
|
||||||
|
AWS_ACCESS_KEY_ID: "{{ restic_s3_key }}"
|
||||||
|
AWS_SECRET_ACCESS_KEY: "{{ restic_s3_secret }}"
|
||||||
|
RESTIC_BACKUP_ARGS: >-
|
||||||
|
--tag arr
|
||||||
|
RESTIC_BACKUP_SOURCES: "/backup"
|
||||||
|
volumes:
|
||||||
|
{% if restic_repo is regex('^/.+') %}
|
||||||
|
- "{{ restic_repo }}:{{ restic_repo }}"
|
||||||
|
{% endif %}
|
||||||
|
- "{{ arrstack_env_dir }}:/backup/{{ arrstack_env_dir }}"
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
networks:
|
networks:
|
||||||
caddy:
|
caddy:
|
||||||
|
|
|
||||||
|
|
@ -7,5 +7,8 @@ stack_grocy_puid: "{{ puid | default(1000) }}"
|
||||||
stack_grocy_pgid: "{{ pgid | default(100) }}"
|
stack_grocy_pgid: "{{ pgid | default(100) }}"
|
||||||
stack_grocy_umask_set: "{{ umask_set | default('022') }}"
|
stack_grocy_umask_set: "{{ umask_set | default('022') }}"
|
||||||
|
|
||||||
|
stack_grocy_restic_enable: true
|
||||||
|
stack_grocy_restic_cron: 0 15 2 * * *
|
||||||
|
|
||||||
stack_grocy_env_dir: /opt/stack_grocy
|
stack_grocy_env_dir: /opt/stack_grocy
|
||||||
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
services:
|
services:
|
||||||
sonarr:
|
grocy:
|
||||||
container_name: grocy
|
container_name: grocy
|
||||||
image: lscr.io/linuxserver/grocy:latest
|
image: lscr.io/linuxserver/grocy:latest
|
||||||
networks:
|
networks:
|
||||||
|
|
@ -16,9 +16,27 @@ services:
|
||||||
caddy: "{{ stack_grocy_subdomain }}"
|
caddy: "{{ stack_grocy_subdomain }}"
|
||||||
caddy.reverse_proxy: "{{ '{{' }}upstreams 80{{ '}}'}}"
|
caddy.reverse_proxy: "{{ '{{' }}upstreams 80{{ '}}'}}"
|
||||||
|
|
||||||
|
{% if restic_enable is not undefined and not false and stack_grocy_restic_enable is not undefined and not false %}
|
||||||
|
backup:
|
||||||
|
image: mazzolino/restic
|
||||||
|
hostname: "{{ ansible_hostname }}"
|
||||||
|
environment:
|
||||||
|
TZ: "{{ restic_tz }}"
|
||||||
|
BACKUP_CRON: "{{ stack_grocy_restic_cron }}"
|
||||||
|
RESTIC_REPOSITORY: "{{ restic_repo }}"
|
||||||
|
RESTIC_PASSWORD: "{{ restic_pass }}"
|
||||||
|
AWS_ACCESS_KEY_ID: "{{ restic_s3_key }}"
|
||||||
|
AWS_SECRET_ACCESS_KEY: "{{ restic_s3_secret }}"
|
||||||
|
RESTIC_BACKUP_ARGS: >-
|
||||||
|
--tag grocy
|
||||||
|
RESTIC_BACKUP_SOURCES: "/backup"
|
||||||
|
volumes:
|
||||||
|
{% if restic_repo is regex('^/.+') %}
|
||||||
|
- "{{ restic_repo }}:{{ restic_repo }}"
|
||||||
|
{% endif %}
|
||||||
|
- "{{ stack_grocy_env_dir }}:/backup/{{ stack_grocy_env_dir }}"
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
networks:
|
networks:
|
||||||
caddy:
|
caddy:
|
||||||
external: true
|
external: true
|
||||||
|
|
||||||
volumes:
|
|
||||||
caddy_data: {}
|
|
||||||
|
|
|
||||||
|
|
@ -7,6 +7,9 @@ stack_paperless_tz: "{{ timezone | default('America/Chicago') }}"
|
||||||
stack_paperless_puid: "{{ puid | default(1000) }}"
|
stack_paperless_puid: "{{ puid | default(1000) }}"
|
||||||
stack_paperless_pgid: "{{ pgid | default(100) }}"
|
stack_paperless_pgid: "{{ pgid | default(100) }}"
|
||||||
|
|
||||||
|
stack_paperless_restic_enable: true
|
||||||
|
stack_paperless_restic_cron: 0 0 2 * * *
|
||||||
|
|
||||||
stack_paperless_env_dir: /opt/stack_paperless
|
stack_paperless_env_dir: /opt/stack_paperless
|
||||||
stack_paperless_serve_dir: /srv
|
stack_paperless_serve_dir: /srv
|
||||||
stack_paperless_serve_dir_create: true
|
stack_paperless_serve_dir_create: true
|
||||||
|
|
@ -65,6 +65,28 @@ services:
|
||||||
environment:
|
environment:
|
||||||
REDIS_ARGS: "--save 60 10"
|
REDIS_ARGS: "--save 60 10"
|
||||||
|
|
||||||
|
{% if restic_enable is not undefined and not false and stack_paperless_restic_enable is not undefined and not false %}
|
||||||
|
backup:
|
||||||
|
image: mazzolino/restic
|
||||||
|
hostname: "{{ ansible_hostname }}"
|
||||||
|
environment:
|
||||||
|
TZ: "{{ restic_tz }}"
|
||||||
|
BACKUP_CRON: "{{ stack_paperless_restic_cron }}"
|
||||||
|
RESTIC_REPOSITORY: "{{ restic_repo }}"
|
||||||
|
RESTIC_PASSWORD: "{{ restic_pass }}"
|
||||||
|
AWS_ACCESS_KEY_ID: "{{ restic_s3_key }}"
|
||||||
|
AWS_SECRET_ACCESS_KEY: "{{ restic_s3_secret }}"
|
||||||
|
RESTIC_BACKUP_ARGS: >-
|
||||||
|
--tag paperless
|
||||||
|
RESTIC_BACKUP_SOURCES: "/backup"
|
||||||
|
volumes:
|
||||||
|
{% if restic_repo is regex('^/.+') %}
|
||||||
|
- "{{ restic_repo }}:{{ restic_repo }}"
|
||||||
|
{% endif %}
|
||||||
|
- "{{ stack_paperless_env_dir }}:/backup/{{ stack_paperless_env_dir }}"
|
||||||
|
- "{{ stack_paperless_serve_dir }}/documents:/backup/{{ stack_paperless_serve_dir }}/documents"
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
networks:
|
networks:
|
||||||
caddy:
|
caddy:
|
||||||
external: true
|
external: true
|
||||||
|
|
|
||||||
69
roles/restic/README.md
Normal file
69
roles/restic/README.md
Normal file
|
|
@ -0,0 +1,69 @@
|
||||||
|
# restic
|
||||||
|
|
||||||
|
Backup maintenance stack.
|
||||||
|
|
||||||
|
Takes care of regularly pruning the backup repository and checking its integrity.
|
||||||
|
Supports any restic backend.
|
||||||
|
Variables set here are used in other roles to individually configure their backups.
|
||||||
|
|
||||||
|
## Defaults
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
restic_tz: US/Chicago
|
||||||
|
```
|
||||||
|
|
||||||
|
The timezone to be used for any cronjobs.
|
||||||
|
Inherits from the global `timezone` variable or can be set individually.
|
||||||
|
|
||||||
|
```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: <restic-pass>
|
||||||
|
```
|
||||||
|
|
||||||
|
The repository url and the restic repository password.
|
||||||
|
Can be of any type restic supports
|
||||||
|
(e.g. `/path/to/backups` for local, `s3:address.to.s3.com` for S3, etc.)
|
||||||
|
See the restic documentation for more information.
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
restic_s3_key: <s3-key>
|
||||||
|
restic_s3_secret: <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.
|
||||||
|
Be aware that go-cron has an extra field in the front for seconds compared to many other implementations.
|
||||||
|
|
||||||
|
```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.
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
restic_notify_success:
|
||||||
|
restic_notify_failure:
|
||||||
|
restic_notify_exit:
|
||||||
|
```
|
||||||
|
|
||||||
|
If restic should notify the user on success/failure/exit (i.e. any outcome process finish).
|
||||||
|
Defaults to no notifications.
|
||||||
|
Uses Apprise and thus takes an [apprise URL](https://github.com/caronc/apprise/wiki) in the form of `ntfy://my-ntfy-channel`.
|
||||||
|
Setting one of these configures _both_ the prune and the check to notify the user if either is done,
|
||||||
|
so currently any success (failure/exit) notification would be doubled for each sucess (failure/exit).
|
||||||
29
roles/restic/defaults/main.yaml
Normal file
29
roles/restic/defaults/main.yaml
Normal file
|
|
@ -0,0 +1,29 @@
|
||||||
|
---
|
||||||
|
# inherited from global
|
||||||
|
restic_enable: true
|
||||||
|
restic_tz: "{{ timezone | default('America/Chicago') }}"
|
||||||
|
|
||||||
|
restic_version: latest
|
||||||
|
restic_auto_init: true
|
||||||
|
|
||||||
|
restic_prune_cron: 0 0 4 * * * # go-cron starts with seconds in first pos
|
||||||
|
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%
|
||||||
|
|
||||||
|
# backup target
|
||||||
|
restic_repo: /opt/stack_restic_backup
|
||||||
|
restic_pass: my-restic-pass
|
||||||
|
restic_s3_key:
|
||||||
|
restic_s3_secret:
|
||||||
|
|
||||||
|
restic_notify_success:
|
||||||
|
restic_notify_failure:
|
||||||
|
restic_notify_exit:
|
||||||
|
|
||||||
|
# S3 example
|
||||||
|
# restic_repo: s3.eu-central-1.wasabisys.com/myrepo
|
||||||
|
# restic_pass: <restic-pass>
|
||||||
|
# restic_s3_key: <s3-key>
|
||||||
|
# restic_s3_secret: <s3-secret>
|
||||||
7
roles/restic/meta/main.yaml
Normal file
7
roles/restic/meta/main.yaml
Normal file
|
|
@ -0,0 +1,7 @@
|
||||||
|
---
|
||||||
|
galaxy_info:
|
||||||
|
author: Marty Oehme
|
||||||
|
description: Installs a restic-based backup maintenance stack.
|
||||||
|
license: GPL-3.0-only
|
||||||
|
min_ansible_version: "2.9"
|
||||||
|
galaxy_tags: []
|
||||||
17
roles/restic/tasks/main.yaml
Normal file
17
roles/restic/tasks/main.yaml
Normal file
|
|
@ -0,0 +1,17 @@
|
||||||
|
---
|
||||||
|
- name: Create local backup directory
|
||||||
|
ansible.builtin.file:
|
||||||
|
state: directory
|
||||||
|
path: "{{ restic_repo }}"
|
||||||
|
owner: root
|
||||||
|
group: root
|
||||||
|
mode: 0770
|
||||||
|
when: restic_repo is regex('^/.+')
|
||||||
|
|
||||||
|
- name: Deploy restic to compose
|
||||||
|
community.docker.docker_compose_v2:
|
||||||
|
project_name: restic
|
||||||
|
definition: "{{ lookup('template', 'docker-compose.yaml.j2') | from_yaml }}"
|
||||||
|
remove_orphans: true
|
||||||
|
wait: true
|
||||||
|
wait_timeout: 60
|
||||||
92
roles/restic/templates/docker-compose.yaml.j2
Normal file
92
roles/restic/templates/docker-compose.yaml.j2
Normal file
|
|
@ -0,0 +1,92 @@
|
||||||
|
services:
|
||||||
|
prune:
|
||||||
|
image: "mazzolino/restic:{{ restic_version }}"
|
||||||
|
hostname: "{{ ansible_hostname }}"
|
||||||
|
networks:
|
||||||
|
- restic_notify
|
||||||
|
environment:
|
||||||
|
TZ: "{{ restic_tz }}"
|
||||||
|
SKIP_INIT: "{{ not restic_auto_init }}"
|
||||||
|
RUN_ON_STARTUP: "true"
|
||||||
|
PRUNE_CRON: "{{ restic_prune_cron }}"
|
||||||
|
RESTIC_FORGET_ARGS: "{{ restic_forget_args }}"
|
||||||
|
RESTIC_REPOSITORY: "{{ restic_repo }}"
|
||||||
|
RESTIC_PASSWORD: "{{ restic_pass }}"
|
||||||
|
AWS_ACCESS_KEY_ID: "{{ restic_s3_key }}"
|
||||||
|
AWS_SECRET_ACCESS_KEY: "{{ restic_s3_secret }}"
|
||||||
|
{% if restic_notify_success != None %}
|
||||||
|
POST_COMMANDS_SUCCESS: |-
|
||||||
|
curl -X POST --data "{\"title\": \"Restic Prune successful\", \"body\": \"{{ ansible_hostname }}\"}" http://notify_success:5000
|
||||||
|
{% endif %}
|
||||||
|
{% if restic_notify_failure != None %}
|
||||||
|
POST_COMMANDS_FAILURE: |-
|
||||||
|
curl -X POST --data "{\"title\": \"Restic Prune failed\", \"body\": \"{{ ansible_hostname }}\"}" http://notify_failure:5000
|
||||||
|
{% endif %}
|
||||||
|
{% if restic_notify_exit != None %}
|
||||||
|
POST_COMMANDS_EXIT: |-
|
||||||
|
curl -X POST --data "{\"title\": \"Restic Prune exited\", \"body\": \"{{ ansible_hostname }}\"}" http://notify_exit:5000
|
||||||
|
{% endif %}
|
||||||
|
{% if restic_repo is regex('^/.+') %}
|
||||||
|
volumes:
|
||||||
|
- "{{ restic_repo }}:{{ restic_repo }}"
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
check:
|
||||||
|
image: "mazzolino/restic:{{ restic_version }}"
|
||||||
|
hostname: docker
|
||||||
|
networks:
|
||||||
|
- restic_notify
|
||||||
|
environment:
|
||||||
|
TZ: "{{ restic_tz }}"
|
||||||
|
SKIP_INIT: true
|
||||||
|
RUN_ON_STARTUP: true
|
||||||
|
CHECK_CRON: "{{ restic_check_cron }}"
|
||||||
|
RESTIC_CHECK_ARGS: "{{ restic_check_args }}"
|
||||||
|
RESTIC_REPOSITORY: "{{ restic_repo }}"
|
||||||
|
RESTIC_PASSWORD: "{{ restic_pass }}"
|
||||||
|
AWS_ACCESS_KEY_ID: "{{ restic_s3_key }}"
|
||||||
|
AWS_SECRET_ACCESS_KEY: "{{ restic_s3_secret }}"
|
||||||
|
{% if restic_notify_success != None %}
|
||||||
|
POST_COMMANDS_SUCCESS: |-
|
||||||
|
curl -X POST --data "{\"title\": \"Restic Check successful\", \"body\": \"{{ ansible_hostname }}\"}" http://notify_success:5000
|
||||||
|
{% endif %}
|
||||||
|
{% if restic_notify_failure != None %}
|
||||||
|
POST_COMMANDS_FAILURE: |-
|
||||||
|
curl -X POST --data "{\"title\": \"Restic Check failed\", \"body\": \"{{ ansible_hostname }}\"}" http://notify_failure:5000
|
||||||
|
{% endif %}
|
||||||
|
{% if restic_notify_exit != None %}
|
||||||
|
POST_COMMANDS_EXIT: |-
|
||||||
|
curl -X POST --data "{\"title\": \"Restic Check exited\", \"body\": \"{{ ansible_hostname }}\"}" http://notify_exit:5000
|
||||||
|
{% endif %}
|
||||||
|
{% if restic_repo is regex('^/.+') %}
|
||||||
|
volumes:
|
||||||
|
- "{{ restic_repo }}:{{ restic_repo }}"
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
{% if restic_notify_success != None %}
|
||||||
|
notify_success:
|
||||||
|
image: mazzolino/apprise-microservice:latest
|
||||||
|
networks:
|
||||||
|
- restic_notify
|
||||||
|
environment:
|
||||||
|
NOTIFICATION_URLS: {{ restic_notify_success }}
|
||||||
|
{% endif %}
|
||||||
|
{% if restic_notify_failure != None %}
|
||||||
|
notify_failure:
|
||||||
|
image: mazzolino/apprise-microservice:latest
|
||||||
|
networks:
|
||||||
|
- restic_notify
|
||||||
|
environment:
|
||||||
|
NOTIFICATION_URLS: {{ restic_notify_failure }}
|
||||||
|
{% endif %}
|
||||||
|
{% if restic_notify_exit != None %}
|
||||||
|
notify_exit:
|
||||||
|
image: mazzolino/apprise-microservice:latest
|
||||||
|
networks:
|
||||||
|
- restic_notify
|
||||||
|
environment:
|
||||||
|
NOTIFICATION_URLS: {{ restic_notify_exit }}
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
networks:
|
||||||
|
restic_notify:
|
||||||
8
roles/restic/vars/main.yaml
Normal file
8
roles/restic/vars/main.yaml
Normal file
|
|
@ -0,0 +1,8 @@
|
||||||
|
---
|
||||||
|
stack_name: restic
|
||||||
|
|
||||||
|
stack_image: "mazzolino/restic"
|
||||||
|
|
||||||
|
stack_compose: "{{ lookup('template', 'docker-stack.yml.j2') | from_yaml }}"
|
||||||
|
|
||||||
|
backup_enable: true
|
||||||
Loading…
Add table
Add a link
Reference in a new issue