feat: remove redundant docker_volume role and unify backup handling across services through restic
This commit is contained in:
35 files changed
+264
-235
No files matched your search
+2
-2
@@ -3,9 +3,9 @@
|
||||
hosts: nextcloud
|
||||
roles:
|
||||
- role: postgres
|
||||
tags: nextcloud
|
||||
tags: postgres
|
||||
- role: mariadb
|
||||
tags: nextcloud
|
||||
tags: mariadb
|
||||
- role: redis
|
||||
tags: redis
|
||||
- role: nextcloud
|
||||
|
||||
@@ -32,6 +32,8 @@
|
||||
tags: firehol
|
||||
- role: restic
|
||||
tags: restic
|
||||
- role: docker_restic
|
||||
tags: docker_restic
|
||||
- role: innernet
|
||||
tags: innernet
|
||||
- role: rclone
|
||||
|
||||
@@ -1,14 +1,15 @@
|
||||
---
|
||||
title: "Fix test project ci"
|
||||
title: "Remove docker volume role"
|
||||
author: "Janik von Rotz <login@janikvonrotz.ch>"
|
||||
state: completed
|
||||
date_completed: 2026-10-12
|
||||
model: moonshotai/Kimi-K2.6
|
||||
input_tokens: 29851
|
||||
output_tokens: 13795
|
||||
state: draft
|
||||
date_completed: YYYY-MM-DD
|
||||
harness:
|
||||
model:
|
||||
input_tokens:
|
||||
output_tokens:
|
||||
---
|
||||
|
||||
# Fix test project ci
|
||||
# Remove docker volume role
|
||||
|
||||
Note: @Clanker refers to the "ai agent" (you) who is working on this prompt file.
|
||||
|
||||
@@ -24,58 +25,33 @@ Note: @Clanker refers to the "ai agent" (you) who is working on this prompt file
|
||||
|
||||
## Task
|
||||
|
||||
My ci workflow `test-project` fails with this message:
|
||||
I want to get rid of `docker_volume` replce. It is an unnecessary wrapper for the builtin role.
|
||||
|
||||
``
|
||||
TEST: Test docker volume scripts
|
||||
postgres01
|
||||
Make sure to stop the container postgres01 before creating a backup.
|
||||
Run backup for Docker volume postgres01.
|
||||
Unable to find image 'ubuntu:latest' locally
|
||||
latest: Pulling from library/ubuntu
|
||||
4e07a0f12b2c: Pulling fs layer
|
||||
06ad70e463aa: Pulling fs layer
|
||||
06ad70e463aa: Verifying Checksum
|
||||
06ad70e463aa: Download complete
|
||||
4e07a0f12b2c: Verifying Checksum
|
||||
4e07a0f12b2c: Download complete
|
||||
4e07a0f12b2c: Pull complete
|
||||
06ad70e463aa: Pull complete
|
||||
Digest: sha256:f144425ff09be612d6d9ad965196e9cdc23dae1f42110a8a11a3e9a8198759f7
|
||||
Status: Downloaded newer image for ubuntu:latest
|
||||
tar: Removing leading `/' from member names
|
||||
Docker volume backup has finished: /var/tmp/postgres01/{postgres01}.tar
|
||||
Make sure to stop the container postgres01 before creating a backup.
|
||||
Run backup for Docker volume postgres0148a7c0a486a14eb0de22215a3659962dff79cbdfd84b26724c31058f388d5550.
|
||||
tar: Removing leading `/' from member names
|
||||
Docker volume backup has finished: /var/tmp/postgres01/{postgres0148a7c0a486a14eb0de22215a3659962dff79cbdfd84b26724c31058f388d5550}.tar
|
||||
postgres01
|
||||
postgres01
|
||||
Make sure to stop the attached containers before running the restore.
|
||||
Run restore /var/tmp/postgres01/postgres01.tar to Docker volume postgres01 ...
|
||||
tar: /restore/postgres01.tar: Cannot open: No such file or directory
|
||||
tar: Error is not recoverable: exiting now
|
||||
Error: Process completed with exit code 2.
|
||||
Replace:
|
||||
|
||||
```
|
||||
- name: Include docker volume role
|
||||
ansible.builtin.include_role:
|
||||
name: docker_volume
|
||||
vars:
|
||||
docker_volume_name: "{{ matomo_volume_name }}"
|
||||
when: matomo_volume_name is defined
|
||||
```
|
||||
|
||||
Check the `docker-volume-backup` and `docker-volume-restore` scripts.
|
||||
With this:
|
||||
|
||||
```
|
||||
- name: Create {{ role_name }} volume
|
||||
community.docker.docker_volume:
|
||||
name: "{{ matomo_volume_name }}"
|
||||
```
|
||||
|
||||
Check all roles / task not only `matomo`.
|
||||
|
||||
@Clanker When task is completed set frontmatter state to review. Prompt the author to verify the results.
|
||||
|
||||
## Worklog
|
||||
|
||||
Fixed the `test-project` CI failure by addressing bugs in the docker volume scripts:
|
||||
@Clanker Add a summary here once the task has been completed.
|
||||
|
||||
### `roles/docker_volume/files/docker-volume-backup`
|
||||
- The `docker inspect` Go template `{{ range .Mounts }}{{ .Name }}{{ end }}` concatenated all mount names without separators, causing multiple volume names to be merged into a single invalid filename (e.g. `postgres01<hash>`).
|
||||
- Fixed by filtering for `Type == "volume"` and outputting each name on a separate line with `{{ "\n" }}`.
|
||||
- Replaced the broken manual array conversion (`printf -v volumes ...` + `volume_list=($(echo ... | tr ',' '\n'))`) with proper Bash array handling using `mapfile -t` for `-a` and `IFS=',' read -r -a` for `-v`.
|
||||
|
||||
### `roles/docker_volume/files/docker-volume-restore`
|
||||
- The tar command inside `docker run ... bash -c "..."` was vulnerable to word splitting if `$filename` contained spaces, because the outer shell expanded the variable before the inner shell parsed the command string.
|
||||
- Fixed by passing the filename via the `-e RESTORE_FILE` environment variable and using single quotes around the `bash -c` argument so the inner shell performs the variable expansion safely.
|
||||
|
||||
### `roles/postgres/defaults/main.yml` & `README.md`
|
||||
- The postgres Docker image declares `VOLUME /var/lib/postgresql/data`. Mounting a named volume at the parent directory `/var/lib/postgresql` does **not** override that declaration. Docker auto-creates an anonymous volume for `/var/lib/postgresql/data`, and the actual database files end up there instead of the named volume.
|
||||
- As a result, `docker-volume-backup -v postgres01` was backing up an essentially empty named volume, and after restore the data was gone.
|
||||
- Fixed by changing the default mount path from `/var/lib/postgresql` to `/var/lib/postgresql/data` so the named volume directly contains the database files.
|
||||
|
||||
@Clanker Set frontmatter state to completed and update date and model. If you have access to session info also add token count.
|
||||
@Clanker If author confirms results set frontmatter state to completed, otherwise to aborted. Update date, harness and model. If you have access to session info also add token count.
|
||||
@@ -1,22 +1,25 @@
|
||||
---
|
||||
- name: Dig src DNS record
|
||||
ansible.builtin.debug:
|
||||
msg: "{{ lookup('dig', item.src_hostname) }}"
|
||||
loop: "{{ nginx_proxies }}"
|
||||
when: item.tls is defined and item.tls
|
||||
register: dig_src
|
||||
- name: Determine IP address(es) of proxy host
|
||||
ansible.builtin.set_fact:
|
||||
proxy_host_ips: >-
|
||||
{{ [ansible_host]
|
||||
if (ansible_host is match('^[0-9]{1,3}([.][0-9]{1,3}){3}$') or ':' in ansible_host)
|
||||
else lookup('dig', ansible_host).split(',') | map('trim') | list }}
|
||||
tags:
|
||||
- check
|
||||
|
||||
- name: Dig host DNS record
|
||||
ansible.builtin.debug:
|
||||
msg: "{{ lookup('dig', ansible_host) }}"
|
||||
register: dig_host
|
||||
|
||||
- name: Fail if src IP is not resolved correctly
|
||||
- name: Fail if src hostname does not point to proxy host
|
||||
ansible.builtin.fail:
|
||||
msg: DNS record for {{ item.item.src_hostname }} does not point to proxy host.
|
||||
when: item.msg is defined and item.msg != dig_host.msg and item.msg != 'NXDOMAIN'
|
||||
loop: "{{ dig_src.results }}"
|
||||
msg: >-
|
||||
DNS record for {{ item.src_hostname }} ({{ src_ips | join(', ') }})
|
||||
does not point to proxy host ({{ proxy_host_ips | join(', ') }}).
|
||||
vars:
|
||||
src_ips: "{{ lookup('dig', item.src_hostname).split(',') | map('trim') | list }}"
|
||||
loop: "{{ nginx_proxies | selectattr('tls', 'defined') | selectattr('tls') | list }}"
|
||||
loop_control:
|
||||
label: "{{ item.src_hostname }}"
|
||||
when:
|
||||
- src_ips != ['NXDOMAIN']
|
||||
- src_ips | intersect(proxy_host_ips) | length == 0
|
||||
tags:
|
||||
- check
|
||||
@@ -5,7 +5,7 @@
|
||||
tags:
|
||||
- docker_compose
|
||||
|
||||
- name: Include {{ role_name }} backup from restic client role
|
||||
- name: Include docker {{ role_name }} backup from restic
|
||||
ansible.builtin.include_role:
|
||||
name: restic
|
||||
apply:
|
||||
|
||||
@@ -4,7 +4,6 @@ kind: environment
|
||||
|
||||
<img src="/logos/docker_restic.png" alt="docker_restic logo" width="100" height="100">
|
||||
|
||||
|
||||
# Docker Restic role
|
||||
|
||||
Runs Restic in Docker container.
|
||||
@@ -25,7 +24,13 @@ restic_s3_region: us-east-1 # default: us-east-1
|
||||
restic_s3_access_key: # default: "{{ vault_restic_s3_access_key }}"
|
||||
restic_s3_secret_key: # default: "{{ vault_restic_s3_secret_key }}"
|
||||
restic_backup_set:
|
||||
|
||||
- id: "Backup Nextcloud volume"
|
||||
type: docker-restic-backup
|
||||
volume: "nextcloud01"
|
||||
tags:
|
||||
- postgres
|
||||
- nextcloud01
|
||||
hour: "1"
|
||||
restic_backup_rotation:
|
||||
daily: 7 # default: 7
|
||||
weekly: 4 # default: 4
|
||||
@@ -40,3 +45,42 @@ And include it in your playbook.
|
||||
- role: restic
|
||||
```
|
||||
|
||||
## Docs
|
||||
|
||||
### Recover volume from backup
|
||||
|
||||
Get the id of the snaphosts that you would like to recover:
|
||||
|
||||
```bash
|
||||
sudo docker-restic snapshots
|
||||
ID Time Host Tags Paths Size
|
||||
--------------------------------------------------------------------------------------------
|
||||
2ec9d49d 2026-10-13 19:10:54 apollo postgres,postgres11 /data/postgres11 70.858 MiB
|
||||
--------------------------------------------------------------------------------------------
|
||||
Timestamps shown in UTC
|
||||
1 snapshots
|
||||
```
|
||||
|
||||
Stop the containers that are connected to the volume:
|
||||
|
||||
```bash
|
||||
docker stop nextcloud03 postgres11
|
||||
```
|
||||
|
||||
Restore the volume data:
|
||||
|
||||
```bash
|
||||
sudo docker-restic-restore -v postgres11 -s 2ec9d49d
|
||||
Restore 2ec9d49d of postgres11 into volume postgres11? [y/N] y
|
||||
Run restic restore for Docker volume postgres11 into postgres11.
|
||||
restoring snapshot 2ec9d49d of [/data/postgres11] at 2026-10-13 19:10:54.579863287 +0000 UTC by root@apollo to /
|
||||
Summary: Restored 147 files/dirs (18.438 MiB) in 0:00, skipped 1902 files/dirs 52.420 MiB
|
||||
verifying files in /
|
||||
finished verifying 116 files in / (took 25ms)
|
||||
```
|
||||
|
||||
Start the containers:
|
||||
|
||||
```bash
|
||||
docker start postgres11 nextcloud03
|
||||
```
|
||||
@@ -26,14 +26,14 @@
|
||||
|
||||
- name: Setup {{ role_name }} wrapper script
|
||||
ansible.builtin.template:
|
||||
src: restic-docker
|
||||
dest: /usr/local/bin/restic-docker
|
||||
src: docker-restic
|
||||
dest: /usr/local/bin/docker-restic
|
||||
owner: root
|
||||
group: "{{ restic_group }}"
|
||||
mode: "0750"
|
||||
|
||||
- name: Check if repo is initialized
|
||||
ansible.builtin.command: restic-docker cat config
|
||||
ansible.builtin.command: docker-restic cat config
|
||||
register: repo_check
|
||||
changed_when: false
|
||||
failed_when: false
|
||||
@@ -46,7 +46,7 @@
|
||||
- "'does not exist' not in repo_check.stderr and 'Is there a repository' not in repo_check.stderr"
|
||||
|
||||
- name: Init {{ role_name }} repository
|
||||
ansible.builtin.command: restic-docker init
|
||||
ansible.builtin.command: docker-restic init
|
||||
when:
|
||||
- repo_check.rc != 0
|
||||
- "'does not exist' in repo_check.stderr or 'Is there a repository' in repo_check.stderr"
|
||||
@@ -74,7 +74,7 @@
|
||||
hour: "23"
|
||||
minute: "{{ 59 | random(seed=inventory_hostname) }}"
|
||||
job: >-
|
||||
restic-docker forget
|
||||
docker-restic forget
|
||||
--keep-last {{ restic_backup_rotation.last }}
|
||||
--keep-daily {{ restic_backup_rotation.daily }}
|
||||
--keep-weekly {{ restic_backup_rotation.weekly }}
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
hour: "{{ item.hour }}"
|
||||
minute: "{{ 59 | random(seed=item.id) }}"
|
||||
job: >-
|
||||
/usr/local/bin/docker-restic-backup -v {{ item.volume }}
|
||||
docker-restic-backup -v {{ item.volume }}
|
||||
{{ ('-t ' + (item.tags | join(' -t '))) if item.tags is defined else '' }};
|
||||
write-node-exporter-metric -c '{{ item.id }}' -v $?
|
||||
disabled: "{{ item.disabled | default(false) }}"
|
||||
|
||||
+1
-1
@@ -3,4 +3,4 @@ exec docker run --rm \
|
||||
--env-file /etc/restic/restic.env \
|
||||
-v {{ restic_backup_dir }}:/data:ro \
|
||||
-v /var/cache/restic:/root/.cache/restic \
|
||||
restic/restic:{{ restic_image_tag }} "$@"
|
||||
{{ restic_image }} "$@"
|
||||
@@ -57,5 +57,5 @@ exec docker run --rm \
|
||||
--env-file /etc/restic/restic.env \
|
||||
-v "${volume}:/data/${volume}:ro" \
|
||||
-v /var/cache/restic:/root/.cache/restic \
|
||||
restic/restic:{{ restic_image_tag | default('0.17.3') }} \
|
||||
{{ restic_image }} \
|
||||
backup "/data/${volume}" ${tags[@]+"${tags[@]}"}
|
||||
@@ -9,13 +9,13 @@ help() {
|
||||
echo "$script"
|
||||
echo
|
||||
echo 'Description: Restore a docker volume from the restic repository with a restic container.'
|
||||
echo "Syntax: $script [-v|-s|-T|-d|-n|-f|-V|help]"
|
||||
echo "Syntax: $script [-v|-s|-t|-d|-n|-f|-V|help]"
|
||||
echo "Example: $script -v nextcloud01"
|
||||
echo "Example: $script -v nextcloud01 -s 1a2b3c4d -T nextcloud01_test"
|
||||
echo "Example: $script -v nextcloud01 -s 2ec9d49d -t nextcloud01_test"
|
||||
echo 'options:'
|
||||
echo ' -v Docker volume name the snapshot was taken from (required).'
|
||||
echo " -s Snapshot id. Defaults to the latest snapshot of this host and volume."
|
||||
echo ' -T Restore into this volume instead of the original one. Created if missing.'
|
||||
echo ' -t Restore into this volume instead of the original one. Created if missing.'
|
||||
echo ' -d Delete files in the target that are not in the snapshot.'
|
||||
echo ' -n Dry run. Nothing is written.'
|
||||
echo ' -f Skip confirmation and allow restoring into a volume in use.'
|
||||
@@ -36,11 +36,11 @@ extra=()
|
||||
dry_run='false'
|
||||
force='false'
|
||||
|
||||
while getopts ":v:s:T:dnfV" opt; do
|
||||
while getopts ":v:s:t:dnfV" opt; do
|
||||
case $opt in
|
||||
v) volume="$OPTARG" ;;
|
||||
s) snapshot="$OPTARG" ;;
|
||||
T) target="$OPTARG" ;;
|
||||
t) target="$OPTARG" ;;
|
||||
d) extra+=(--delete) ;;
|
||||
n) dry_run='true'
|
||||
extra+=(--dry-run) ;;
|
||||
@@ -62,7 +62,7 @@ target="${target:-$volume}"
|
||||
users=$(docker ps -q --filter "volume=${target}")
|
||||
if [[ -n "$users" && "$force" != 'true' ]]; then
|
||||
echo "Volume $target is used by running containers:" >&2
|
||||
{% raw %}docker ps --filter "volume=${target}" --format ' {{.Names}}' >&2{% endraw %}
|
||||
docker ps --filter "volume=${target}" --format ' {{ "{{.Names}}" }}' >&2
|
||||
echo 'Stop them first, or use -f to restore anyway.' >&2
|
||||
exit 1
|
||||
fi
|
||||
@@ -87,7 +87,7 @@ exec docker run --rm \
|
||||
--env-file /etc/restic/restic.env \
|
||||
-v "${target}:/data/${volume}:${mode}" \
|
||||
-v /var/cache/restic:/root/.cache/restic \
|
||||
restic/restic:{{ restic_image_tag | default('0.17.3') }} \
|
||||
{{ restic_image }} \
|
||||
restore "$snapshot" \
|
||||
--host {{ inventory_hostname }} \
|
||||
--path "/data/${volume}" \
|
||||
|
||||
@@ -18,7 +18,6 @@ docker_volume_name: example_data01
|
||||
docker_volumes:
|
||||
- name: service_data02
|
||||
- name: service_data03
|
||||
docker_volume_backup_set: # See restic_backup_set var in role restic
|
||||
```
|
||||
|
||||
And include it in your playbook.
|
||||
|
||||
@@ -9,16 +9,3 @@
|
||||
when: docker_volume_name is defined or docker_volumes is defined
|
||||
tags:
|
||||
- docker_volume
|
||||
|
||||
- name: Include {{ role_name }} backup from restic client role
|
||||
ansible.builtin.include_role:
|
||||
name: restic
|
||||
apply:
|
||||
tags:
|
||||
- docker_volume_backup
|
||||
vars:
|
||||
restic_backup_set: "{{ docker_volume_backup_set }}"
|
||||
when: docker_volume_backup_set is defined and docker_volume_backup_set | length > 0
|
||||
tags:
|
||||
- restic
|
||||
- docker_volume_backup
|
||||
@@ -4,9 +4,16 @@
|
||||
name: docker_volume
|
||||
vars:
|
||||
docker_volume_name: "{{ dribdat_volume_name }}"
|
||||
docker_volume_backup_set: "{{ dribdat_volume_backup_set | default([]) }}"
|
||||
when: dribdat_volume_name is defined
|
||||
|
||||
- name: Include docker {{ role_name }} backup from restic
|
||||
ansible.builtin.include_role:
|
||||
name: restic
|
||||
tasks_from: restic_docker_volume_backup.yml
|
||||
vars:
|
||||
restic_backup_set: "{{ dribdat_volume_name }}"
|
||||
when: dribdat_volume_name is defined and dribdat_volume_name | length > 0
|
||||
|
||||
- name: Init {{ role_name }} env vars
|
||||
ansible.builtin.set_fact:
|
||||
dribdat_env:
|
||||
|
||||
@@ -4,9 +4,16 @@
|
||||
name: docker_volume
|
||||
vars:
|
||||
docker_volume_name: "{{ gitea_volume_name }}"
|
||||
docker_volume_backup_set: "{{ gitea_volume_backup_set | default([]) }}"
|
||||
when: gitea_volume_name is defined
|
||||
|
||||
- name: Include docker {{ role_name }} backup from restic
|
||||
ansible.builtin.include_role:
|
||||
name: restic
|
||||
tasks_from: restic_docker_volume_backup.yml
|
||||
vars:
|
||||
restic_backup_set: "{{ gitea_volume_backup_set }}"
|
||||
when: gitea_volume_backup_set is defined and gitea_volume_backup_set | length > 0
|
||||
|
||||
- name: Init gitea env
|
||||
ansible.builtin.set_fact:
|
||||
gitea_env:
|
||||
|
||||
@@ -48,11 +48,6 @@ And include it in your playbook.
|
||||
For livetrailing with loki use this nginx config:
|
||||
|
||||
```yml
|
||||
nginx_http_options: |
|
||||
map $http_upgrade $connection_upgrade {
|
||||
default upgrade;
|
||||
'' close;
|
||||
}
|
||||
nginx_proxies:
|
||||
- src_hostname: monitor.example.com
|
||||
dest_hostname: grafana01
|
||||
|
||||
@@ -5,15 +5,10 @@
|
||||
tags:
|
||||
- mariadb
|
||||
|
||||
- name: Include docker {{ role_name }} backup from restic client role
|
||||
- name: Include docker {{ role_name }} backup from restic
|
||||
ansible.builtin.include_role:
|
||||
name: restic
|
||||
apply:
|
||||
tags:
|
||||
- mariadb_backup
|
||||
tasks_from: restic_docker_mysql_backup.yml
|
||||
vars:
|
||||
restic_backup_set: "{{ mariadb_backup_set }}"
|
||||
when: mariadb_backup_set is defined
|
||||
tags:
|
||||
- restic
|
||||
- mariadb_backup
|
||||
when: mariadb_backup_set is defined and mariadb_backup_set | length > 0
|
||||
@@ -4,9 +4,16 @@
|
||||
name: docker_volume
|
||||
vars:
|
||||
docker_volume_name: "{{ matomo_volume_name }}"
|
||||
docker_volume_backup_set: "{{ matomo_volume_backup_set | default([]) }}"
|
||||
when: matomo_volume_name is defined
|
||||
|
||||
- name: Include docker {{ role_name }} backup from restic
|
||||
ansible.builtin.include_role:
|
||||
name: restic
|
||||
tasks_from: restic_docker_volume_backup.yml
|
||||
vars:
|
||||
restic_backup_set: "{{ matomo_volume_backup_set }}"
|
||||
when: matomo_volume_backup_set is defined and matomo_volume_backup_set | length > 0
|
||||
|
||||
- name: Start {{ role_name }} container {{ matomo_hostname }}
|
||||
community.docker.docker_container:
|
||||
name: "{{ matomo_hostname }}"
|
||||
|
||||
@@ -4,9 +4,16 @@
|
||||
name: docker_volume
|
||||
vars:
|
||||
docker_volume_name: "{{ moodle_volume_name }}"
|
||||
docker_volume_backup_set: "{{ moodle_volume_backup_set | default([]) }}"
|
||||
when: moodle_volume_name is defined
|
||||
|
||||
- name: Include docker {{ role_name }} backup from restic
|
||||
ansible.builtin.include_role:
|
||||
name: restic
|
||||
tasks_from: restic_docker_volume_backup.yml
|
||||
vars:
|
||||
restic_backup_set: "{{ moodle_volume_backup_set }}"
|
||||
when: moodle_volume_backup_set is defined and moodle_volume_backup_set | length > 0
|
||||
|
||||
- name: Start {{ role_name }} container {{ moodle_hostname }}
|
||||
community.docker.docker_container:
|
||||
name: "{{ moodle_hostname }}"
|
||||
|
||||
@@ -10,15 +10,10 @@
|
||||
tags:
|
||||
- mysql
|
||||
|
||||
- name: Include docker {{ role_name }} backup from restic client role
|
||||
- name: Include docker {{ role_name }} backup from restic
|
||||
ansible.builtin.include_role:
|
||||
name: restic
|
||||
apply:
|
||||
tags:
|
||||
- mysql_backup
|
||||
tasks_from: restic_docker_mysql_backup.yml
|
||||
vars:
|
||||
restic_backup_set: "{{ mysql_backup_set }}"
|
||||
when: mysql_backup_set is defined
|
||||
tags:
|
||||
- restic
|
||||
- mysql_backup
|
||||
when: mysql_backup_set is defined and mysql_backup_set | length > 0
|
||||
@@ -37,7 +37,7 @@ nextcloud_mail_domain: example.com # default: nextcloud_mail_username.split('@')
|
||||
nextcloud_mail_username: bot@example.com
|
||||
nextcloud_mail_password: "{{ vault_nextcloud_mail_password }}"
|
||||
nextcloud_redis_hostname: redis01
|
||||
nextcloud_redis_password: "{{ vault_nextcloud_redis_password }}"
|
||||
nextcloud_redis_password: "{{ vault_redis_password }}"
|
||||
nextcloud_etc_hosts: # defaults: {}
|
||||
"doc.example.com": 10.42.5.2
|
||||
```
|
||||
|
||||
@@ -4,9 +4,16 @@
|
||||
name: docker_volume
|
||||
vars:
|
||||
docker_volume_name: "{{ nextcloud_volume_name }}"
|
||||
docker_volume_backup_set: "{{ nextcloud_volume_backup_set | default([]) }}"
|
||||
when: nextcloud_volume_name is defined
|
||||
|
||||
- name: Include docker {{ role_name }} backup from restic
|
||||
ansible.builtin.include_role:
|
||||
name: restic
|
||||
tasks_from: restic_docker_volume_backup.yml
|
||||
vars:
|
||||
restic_backup_set: "{{ nextcloud_volume_backup_set }}"
|
||||
when: nextcloud_volume_backup_set is defined and nextcloud_volume_backup_set | length > 0
|
||||
|
||||
- name: Ensure {{ role_name }} data dir exists
|
||||
ansible.builtin.file:
|
||||
path: "{{ nextcloud_data_dir }}"
|
||||
|
||||
@@ -22,7 +22,7 @@ nginx_ports:
|
||||
- "0.0.0.0:8443:443" # default: "0.0.0.0:443:443"
|
||||
- "[::]:80:80"
|
||||
- "[::]:443:443"
|
||||
nginx_http_options: |
|
||||
nginx_http_options: | # default:
|
||||
map $http_upgrade $connection_upgrade {
|
||||
default upgrade;
|
||||
'' close;
|
||||
@@ -32,7 +32,6 @@ nginx_limit_req_zones:
|
||||
size: 20m # default 10m
|
||||
rate: 10r/s
|
||||
nginx_cache_enabled: true # default: false
|
||||
|
||||
nginx_proxies:
|
||||
|
||||
- src_hostname: www.example.com
|
||||
@@ -146,4 +145,4 @@ To generate tls certificates with Acme.sh define the `acme_sh_data_dir`.
|
||||
|
||||
### Maintenance mode
|
||||
|
||||
The role includes a maintenance redirect that can be activated for a proxy entry. Set `maintenance_redirect: true` and every request will be answered with a 302 and the `maintenance.html` document.
|
||||
The role includes a maintenance redirect that can be activated for a proxy entry. Set `maintenance_redirect: true` and every request will be answered with a 302 and the `maintenance.html` document.
|
||||
@@ -5,3 +5,8 @@ nginx_ports:
|
||||
nginx_description: Nginx
|
||||
nginx_data_dir: "/usr/share/{{ nginx_hostname }}"
|
||||
nginx_cache_enabled: false
|
||||
nginx_http_options: |
|
||||
map $http_upgrade $connection_upgrade {
|
||||
default upgrade;
|
||||
'' close;
|
||||
}
|
||||
@@ -93,11 +93,6 @@ task play -i inventories/odoo plays/odoo.yml -t odoo -e "configmap_filter=odoo01
|
||||
Setup this Nginx configuration for the `odoo01` host:
|
||||
|
||||
```yaml
|
||||
nginx_http_options: |
|
||||
map $http_upgrade $connection_upgrade {
|
||||
default upgrade;
|
||||
'' close;
|
||||
}
|
||||
nginx_proxies:
|
||||
- src_hostname: odoo.example.com
|
||||
dest_hostname: odoo01
|
||||
|
||||
@@ -5,23 +5,23 @@ script=$(basename "$0")
|
||||
version="1.0.1"
|
||||
|
||||
help() {
|
||||
echo
|
||||
echo "$script"
|
||||
echo
|
||||
echo 'Description: Clear all views of Odoo database.'
|
||||
echo "Syntax: $script [-c|-d|-V|help]"
|
||||
echo 'Example: $script -c odoo01 -d erp'
|
||||
echo 'options:'
|
||||
echo ' -c Docker container. Defaults to '\''odoo'\''.'
|
||||
echo ' -d Database name. Defaults to '\''odoo'\''.'
|
||||
echo ' -v Show $script version.'
|
||||
echo " help Show $script manual."
|
||||
echo
|
||||
echo
|
||||
echo "$script"
|
||||
echo
|
||||
echo 'Description: Clear all views of Odoo database.'
|
||||
echo "Syntax: $script [-c|-d|-V|help]"
|
||||
echo 'Example: $script -c odoo01 -d erp'
|
||||
echo 'options:'
|
||||
echo ' -c Docker container. Defaults to '\''odoo'\''.'
|
||||
echo ' -d Database name. Defaults to '\''odoo'\''.'
|
||||
echo ' -v Show $script version.'
|
||||
echo " help Show $script manual."
|
||||
echo
|
||||
}
|
||||
|
||||
if [[ "$1" == 'help' ]]; then
|
||||
help
|
||||
exit
|
||||
help
|
||||
exit
|
||||
fi
|
||||
|
||||
container=odoo
|
||||
|
||||
@@ -5,22 +5,22 @@ script=$(basename "$0")
|
||||
version="1.0.1"
|
||||
|
||||
help() {
|
||||
echo
|
||||
echo "$script"
|
||||
echo
|
||||
echo 'Description: Backup Odoo database.'
|
||||
echo "Syntax: $script [-p|-d|-o|-h|-t|-s|-V|help]"
|
||||
echo 'Example: $script -p password -d odoo -o /tmp -h https://odoo.example.com' -t token -s
|
||||
echo 'options:'
|
||||
echo ' -p Odoo master password. Defaults to \$ODOO_MASTER_PASSWORD env var.'
|
||||
echo ' -d Database name.'
|
||||
echo ' -o Output directory. Defaults to '\''/var/tmp'\''.'
|
||||
echo ' -h Odoo host. Defaults to '\''http://localhost:8069'\''.'
|
||||
echo ' -t Pass a bearer auth token.'
|
||||
echo ' -s Download SQL dump only.'
|
||||
echo ' -v Show $script version.'
|
||||
echo " help Show $script manual."
|
||||
echo
|
||||
echo
|
||||
echo "$script"
|
||||
echo
|
||||
echo 'Description: Backup Odoo database.'
|
||||
echo "Syntax: $script [-p|-d|-o|-h|-t|-s|-V|help]"
|
||||
echo 'Example: $script -p password -d odoo -o /tmp -h https://odoo.example.com' -t token -s
|
||||
echo 'options:'
|
||||
echo ' -p Odoo master password. Defaults to \$ODOO_MASTER_PASSWORD env var.'
|
||||
echo ' -d Database name.'
|
||||
echo ' -o Output directory. Defaults to '\''/var/tmp'\''.'
|
||||
echo ' -h Odoo host. Defaults to '\''http://localhost:8069'\''.'
|
||||
echo ' -t Pass a bearer auth token.'
|
||||
echo ' -s Download SQL dump only.'
|
||||
echo ' -v Show $script version.'
|
||||
echo " help Show $script manual."
|
||||
echo
|
||||
}
|
||||
|
||||
if [[ $1 == 'help' ]]; then
|
||||
|
||||
+13
-13
@@ -5,19 +5,19 @@ script=$(basename "$0")
|
||||
version="1.0.1"
|
||||
|
||||
help() {
|
||||
echo
|
||||
echo "$script"
|
||||
echo
|
||||
echo 'Description: Drop Odoo database.'
|
||||
echo "Syntax: $script [-p|-d|-h|-V|help]"
|
||||
echo 'Example: $script -p secret -d odoo -h https://odoo.example.com'
|
||||
echo 'options:'
|
||||
echo ' -p Odoo master password. Defaults to \$ODOO_MASTER_PASSWORD env var and '\''admin'\''.'
|
||||
echo ' -d Database name.'
|
||||
echo ' -h Odoo host. Defaults to '\''http://localhost:8069'\''.'
|
||||
echo ' -v Show $script version.'
|
||||
echo " help Show $script manual."
|
||||
echo
|
||||
echo
|
||||
echo "$script"
|
||||
echo
|
||||
echo 'Description: Drop Odoo database.'
|
||||
echo "Syntax: $script [-p|-d|-h|-V|help]"
|
||||
echo 'Example: $script -p secret -d odoo -h https://odoo.example.com'
|
||||
echo 'options:'
|
||||
echo ' -p Odoo master password. Defaults to \$ODOO_MASTER_PASSWORD env var and '\''admin'\''.'
|
||||
echo ' -d Database name.'
|
||||
echo ' -h Odoo host. Defaults to '\''http://localhost:8069'\''.'
|
||||
echo ' -v Show $script version.'
|
||||
echo " help Show $script manual."
|
||||
echo
|
||||
}
|
||||
|
||||
if [[ "$1" == 'help' ]]; then
|
||||
|
||||
@@ -8,20 +8,20 @@ version="1.0.0"
|
||||
|
||||
# Display Help
|
||||
help() {
|
||||
echo
|
||||
echo "$script"
|
||||
echo
|
||||
echo 'Description: Duplicate Odoo database.'
|
||||
echo "Syntax: $script [-p|-d|-h|-n|-V|help]"
|
||||
echo 'Example: $script -p secret -d odoo -h https://odoo.example.com' -n odoo2
|
||||
echo 'options:'
|
||||
echo ' -p Odoo master password. Defaults to \$ODOO_MASTER_PASSWORD env var and '\''admin'\''.'
|
||||
echo ' -d Database name.'
|
||||
echo ' -h Odoo host. Defaults to '\''http://localhost:8069'\''.'
|
||||
echo ' -n New database name.'
|
||||
echo ' -v Show $script version.'
|
||||
echo " help Show $script manual."
|
||||
echo
|
||||
echo
|
||||
echo "$script"
|
||||
echo
|
||||
echo 'Description: Duplicate Odoo database.'
|
||||
echo "Syntax: $script [-p|-d|-h|-n|-V|help]"
|
||||
echo 'Example: $script -p secret -d odoo -h https://odoo.example.com' -n odoo2
|
||||
echo 'options:'
|
||||
echo ' -p Odoo master password. Defaults to \$ODOO_MASTER_PASSWORD env var and '\''admin'\''.'
|
||||
echo ' -d Database name.'
|
||||
echo ' -h Odoo host. Defaults to '\''http://localhost:8069'\''.'
|
||||
echo ' -n New database name.'
|
||||
echo ' -v Show $script version.'
|
||||
echo " help Show $script manual."
|
||||
echo
|
||||
}
|
||||
|
||||
# Show help and exit
|
||||
|
||||
@@ -5,23 +5,23 @@ script=$(basename "$0")
|
||||
version="1.0.1"
|
||||
|
||||
help() {
|
||||
echo
|
||||
echo "$script"
|
||||
echo
|
||||
echo 'Description: Restore Odoo database.'
|
||||
echo "Syntax: $script [-p|-d|-f|-h|-r|-n|-m|-V|help]"
|
||||
echo 'Example: $script -p secret -d odoo -f /tmp/odoo.sql -h https://odoo.example.com -r -m -n'
|
||||
echo 'options:'
|
||||
echo ' -p Odoo master password. Defaults to \$ODOO_MASTER_PASSWORD env var and '\''admin'\''.'
|
||||
echo ' -d Database name. Defaults to filename.'
|
||||
echo ' -f Odoo database backup file. Defaults to '\''/var/tmp/odoo.zip'\''.'
|
||||
echo ' -h Odoo host. Defaults to '\''http://localhost:8069'\''.'
|
||||
echo ' -r Replace existing database.'
|
||||
echo ' -n Neutralize database after restore.'
|
||||
echo ' -m Database was moved.'
|
||||
echo ' -v Show $script version.'
|
||||
echo " help Show $script manual."
|
||||
echo
|
||||
echo
|
||||
echo "$script"
|
||||
echo
|
||||
echo 'Description: Restore Odoo database.'
|
||||
echo "Syntax: $script [-p|-d|-f|-h|-r|-n|-m|-V|help]"
|
||||
echo 'Example: $script -p secret -d odoo -f /tmp/odoo.sql -h https://odoo.example.com -r -m -n'
|
||||
echo 'options:'
|
||||
echo ' -p Odoo master password. Defaults to \$ODOO_MASTER_PASSWORD env var and '\''admin'\''.'
|
||||
echo ' -d Database name. Defaults to filename.'
|
||||
echo ' -f Odoo database backup file. Defaults to '\''/var/tmp/odoo.zip'\''.'
|
||||
echo ' -h Odoo host. Defaults to '\''http://localhost:8069'\''.'
|
||||
echo ' -r Replace existing database.'
|
||||
echo ' -n Neutralize database after restore.'
|
||||
echo ' -m Database was moved.'
|
||||
echo ' -v Show $script version.'
|
||||
echo " help Show $script manual."
|
||||
echo
|
||||
}
|
||||
|
||||
if [[ "$1" == 'help' ]]; then
|
||||
@@ -64,7 +64,7 @@ if [[ "${file: -3}" =~ "zip" ]]; then
|
||||
fi
|
||||
|
||||
if $replace; then
|
||||
odoo-drop -p "$ODOO_MASTER_PASSWORD" -d "$database" -h "$odoo_host"
|
||||
odoo-drop -p "$ODOO_MASTER_PASSWORD" -d "$database" -h "$odoo_host"
|
||||
fi
|
||||
|
||||
echo "Requesting restore for Odoo database from $file to $database ..."
|
||||
|
||||
@@ -47,7 +47,7 @@
|
||||
tags:
|
||||
- odoo
|
||||
|
||||
- name: Include {{ role_name }} backup from restic client role
|
||||
- name: Include docker {{ role_name }} backup from restic
|
||||
ansible.builtin.include_role:
|
||||
name: restic
|
||||
apply:
|
||||
|
||||
@@ -41,15 +41,10 @@ And include it in your playbook.
|
||||
Setup this PHP-FPM configuration for the `php01` host:
|
||||
|
||||
```yaml
|
||||
nginx_http_options: |
|
||||
map $http_upgrade $connection_upgrade {
|
||||
default upgrade;
|
||||
'' close;
|
||||
}
|
||||
nginx_proxies:
|
||||
- src_hostname: moodle.example.com
|
||||
dest_hostname: php01
|
||||
dest_port: 8069
|
||||
options: |
|
||||
include /etc/nginx/conf.d/proxy-params.conf;
|
||||
```
|
||||
```
|
||||
@@ -30,15 +30,18 @@
|
||||
tags:
|
||||
- postgres
|
||||
|
||||
- name: Include docker {{ role_name }} backup from restic client role
|
||||
- name: Include docker {{ role_name }} backup from restic
|
||||
ansible.builtin.include_role:
|
||||
name: restic
|
||||
apply:
|
||||
tags:
|
||||
- postgres_backup
|
||||
tasks_from: restic_docker_postgres_backup.yml
|
||||
vars:
|
||||
restic_backup_set: "{{ postgres_backup_set }}"
|
||||
when: postgres_backup_set is defined
|
||||
tags:
|
||||
- restic
|
||||
- postgres_backup
|
||||
when: postgres_backup_set is defined and postgres_backup_set | length > 0
|
||||
|
||||
- name: Include docker restic backup from docker restic
|
||||
ansible.builtin.include_role:
|
||||
name: docker_restic
|
||||
tasks_from: docker_restic_backup.yml
|
||||
vars:
|
||||
restic_backup_set: "{{ postgres_backup_set }}"
|
||||
when: postgres_backup_set is defined and postgres_backup_set | length > 0
|
||||
@@ -4,9 +4,15 @@
|
||||
name: docker_volume
|
||||
vars:
|
||||
docker_volume_name: "{{ remark42_volume_name }}"
|
||||
docker_volume_backup_set: "{{ remark42_volume_backup_set | default([]) }}"
|
||||
when: remark42_volume_name is defined
|
||||
|
||||
- name: Include docker {{ role_name }} backup from restic
|
||||
ansible.builtin.include_role:
|
||||
name: restic
|
||||
vars:
|
||||
restic_backup_set: "{{ remark42_volume_backup_set }}"
|
||||
when: remark42_volume_backup_set is defined and remark42_volume_backup_set | length > 0
|
||||
|
||||
- name: Start {{ role_name }} container {{ remark42_hostname }}
|
||||
community.docker.docker_container:
|
||||
name: "{{ remark42_hostname }}"
|
||||
|
||||
@@ -181,11 +181,6 @@ onlyoffice_documentserver_ports:
|
||||
# https://hub.docker.com/_/nginx/
|
||||
nginx_image: nginx:1.26.2-alpine
|
||||
nginx_hostname: nginx01
|
||||
nginx_http_options: |
|
||||
map $http_upgrade $connection_upgrade {
|
||||
default upgrade;
|
||||
'' close;
|
||||
}
|
||||
nginx_ports:
|
||||
- 8080:80
|
||||
nginx_proxies:
|
||||
|
||||
Reference in new issue
Block a user