feat(backup): decide stop_required for every service with a backed-up volume

baudolo stops every container on a volume before the authoritative copy
unless its image is listed via --images-no-stop-required. Leaving the
marker out silently picked "stop": the Stalwart webmail start that the
backup cycle triggered got SIGKILLed mid `composer update` (CI run
40625679270), and 71 services that mount a named volume had never
decided either way.

- The marker is now `backup.stop_required` (true = stop first, false =
  copy live), replacing the double-negated `no_stop_required`; the 50
  existing declarations are inverted unchanged. backup_image takes the
  marker and the wanted value explicitly:
  lookup('backup_image', 'stop_required', false) still feeds
  --images-no-stop-required, lookup('backup_image', 'disabled', true)
  the skip list.
- The 71 undecided services carry researched values (repo files plus
  upstream backup guidance: GitLab, Jenkins, Elastic, RabbitMQ, Typesense,
  Qdrant, OpenLDAP, Prometheus, Moodle, ClamAV, Alertmanager, ...): engine
  files, git repositories, SQLite, mnesia and multi-file state stop; image
  code, write-once blob stores with metadata in the database and
  atomically rewritten files copy live. Stalwart's main service stays
  stopped until /var/lib/stalwart is verified to hold only logs.
- Re-obtainable data is no longer backed up at all (`backup: false` on
  the volume): model weights, ClamAV signatures, SearXNG config/cache,
  transient RabbitMQ queues, Funkwhale's Typesense index, the meta clone,
  the agent-broker socket dir, coturn's unused data dir, and volumes no
  image reads (Decidim's /app paths outside /code, BookWyrm's /app/data
  which v0.9.3 never reads, FusionDirectory's measured-empty dir).
- The backup lookup only matches what actually runs once the role
  declares it: Bluesky's broker (`custom: bluesky_broker`) and Decidim
  (`custom: true`) declare their custom build, BookWyrm's worker/migrate,
  EspoCRM's daemon/websocket, Moodle's cron and OpenProject's proxy use
  their owner's image, and the templates drop their render-time
  overrides. Decidim deploys decidim_custom:0.31.6 and BookWyrm
  bookwyrm_custom:3.11-slim from now on; a BookWyrm ref bump still
  rebuilds through the build-args digest.
- test_backup_stop_decision_declared requires the boolean on every
  service with its own image that mounts a backed-up named volume;
  test_stop_required replaces the old integrity test.

Measured against HEAD: 43 -> 78 services copied live, none moved the
other way; 14 -> 30 volumes skipped.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
kevinveenbirkenbachandClaude Opus 5.5 committed 2026-10-28 15:10:24 +01:00
1 parent a8923690c3
commit fdf1a33c5f
113 files changed
+393 -123

No files matched your search

+1 -1
View File
@@ -109,7 +109,7 @@ redis:
erpnext:
backup:
no_stop_required: false # Frappe's bench backup requires a quiesced site
stop_required: true # Frappe's bench backup requires a quiesced site
image: frappe/erpnext
version: "X.Y.Z" # latest stable semver at the time of the PR
name: erpnext
+1 -1
View File
@@ -93,7 +93,7 @@ tor:
version: "<pinned tor x.y.z>"
name: tor
backup:
no_stop_required: false # stop for consistent key-volume copy
stop_required: true # stop for consistent key-volume copy
lifecycle: alpha
# no public ports; SocksPort/ControlPort bind 127.0.0.1 only
```
+2 -2
View File
@@ -117,7 +117,7 @@ openbao:
internal: { http: 8200 }
local: { http: <allocate via the suggester> }
backup:
no_stop_required: false
stop_required: true
run_after:
- svc-db-openldap
- web-app-keycloak
@@ -286,7 +286,7 @@ cluster_addr = "http://127.0.0.1:8201"
### Backup & restore
- [x] The `container_backup` service is wired with `backup.no_stop_required: false`, so the container is quiesced for a consistent copy of the raft volume.
- [x] The `container_backup` service is wired with `backup.stop_required: true`, so the container is quiesced for a consistent copy of the raft volume.
- [x] A restore procedure is documented and executed once end to end: restore the volume, redeploy, and confirm the instance auto-unseals and a previously stored secret is still readable. Drill run on the variant-2 stack: container quiesced, `openbao_data` archived (33 MB), the live volume **wiped to zero entries**, restored from the archive, and restarted — OpenBao came back `initialized: true, sealed: false` with the secret, the PKI root CA and all five policies recovered. This also confirms the documented dependency: the restored store is only readable because the seal key in the inventory was unchanged.
- [x] The README states explicitly that the volume backup is **worthless without the seal key**, that the seal key's authoritative home is the encrypted inventory (it is not covered by `svc-bkp-secrets-2-local`, whose sources are `DIR_SECRETS`, the CA and the ACME material), and what the recovery keys can and cannot do.
- [x] The README states the consequence of Decision #2 that surfaced during implementation: because the root token is revoked and the recovery keys are **not** persisted (persisting them would be the write-back the AppRole bootstrap exists to avoid), the Ansible AppRole is the *only* administrative path into the instance. Losing or out-of-band-changing those credentials means rebuilding from the volume backup plus the seal key.
@@ -1,5 +1,7 @@
---
agent-broker:
backup:
stop_required: false
modes:
compose:
enabled: true
@@ -43,6 +45,8 @@ agent-broker:
# nocheck: shared
# nocheck: dynamic-flag
socket-proxy:
backup:
stop_required: false
bond: 1
enabled: true
image: wollomatic/socket-proxy
@@ -10,6 +10,7 @@ docker_sock:
engine_socket:
type: volume
backup: false
mounts:
- service: socket-proxy
target: &engine_socket_dir /run/agent-engine
+1 -1
View File
@@ -12,7 +12,7 @@ litellm:
enabled: true
shared: true
backup:
no_stop_required: true
stop_required: false
image: ghcr.io/berriai/litellm
version: main-v1.77.7-stable
name: litellm
+1 -1
View File
@@ -12,7 +12,7 @@ lmstudio:
enabled: true
shared: true
backup:
no_stop_required: true
stop_required: false
image: ubuntu
version: "22.04"
custom: true
+2
View File
@@ -1,6 +1,8 @@
---
# nocheck: playwright-service-flag — translation engine without a browser surface of its own
ltengine:
backup:
stop_required: false
name: ltengine
healthcheck:
flavor: http_status
+1
View File
@@ -3,6 +3,7 @@
# nocheck: embedded-state-on-nfs content-addressed GGUF weights, downloaded once and read-only after
ltengine_models:
type: volume
backup: false
mounts:
- service: ltengine
target: /models
@@ -1,6 +1,8 @@
---
# nocheck: playwright-service-flag — translation engine without a browser surface of its own
nllb-engine:
backup:
stop_required: false
name: nllb-engine
healthcheck:
flavor: http_status
@@ -3,6 +3,7 @@
# nocheck: nfs-false-data-loss Reason: a node that fetched the checkpoint holds the same files every other node would fetch, so nothing written here has to reach another node
nllb_models: # nocheck: embedded-state-on-nfs content-addressed checkpoint, read-only after the first download
type: volume
backup: false
mounts:
- service: nllb-engine
target: /models
+1 -1
View File
@@ -11,7 +11,7 @@ ollama:
enabled: true
shared: true
backup:
no_stop_required: true
stop_required: false
image: ollama/ollama
version: 0.40.12
name: ollama
+2
View File
@@ -1,6 +1,8 @@
---
# nocheck: playwright-service-flag - internal search backend consumed over the container network
searxng:
backup:
stop_required: false
modes:
compose:
enabled: true
+2
View File
@@ -9,6 +9,7 @@ searxng_settings:
target: /etc/searxng/settings.yml
searxng_config:
type: volume
backup: false
# nocheck: nfs-false-data-loss Reason: holds the image's own /etc/searxng copy, which docker seeds per node on first start; the deployment's settings.yml is bind-mounted over it, so nothing a replica writes here has to reach another replica
nfs: false
mounts:
@@ -16,6 +17,7 @@ searxng_config:
target: /etc/searxng
searxng_cache:
type: volume
backup: false
# nocheck: nfs-false-data-loss Reason: derived search cache, rebuilt from the upstream engines on demand; shared over NFS every replica would write the same keys into one tree for no gain
nfs: false
mounts:
+1 -1
View File
@@ -39,7 +39,7 @@ flowchart TD
- **Per-container snapshots:** rsync `--link-dest` snapshots deduplicate unchanged files across runs.
- **Database-aware:** consumer apps seed their connection metadata into a central `databases.csv`, so the same run can dump SQL state alongside the file payload.
- **Live-aware:** containers tagged `no_stop_required` stay running during the dump; others stop briefly and resume.
- **Live-aware:** containers tagged `stop_required: false` stay running during the dump; others stop briefly and resume.
- **Snapshot-aware:** on a btrfs data root the whole run is captured from one atomic filesystem snapshot with no container stopped; the host is probed before every run and falls back to the live copy when a snapshot would not be faithful.
- **Systemd-driven:** a generated unit fires on the configured schedule (`SYS_SCHEDULE_BACKUP_CONTAINER_TO_LOCAL`), serialised against other backup/cleanup/repair groups by `sys-lock`.
- **Self-cleaning:** failed backup attempts are torn down by `sys-ctl-cln-faild-bkps` so a broken run cannot poison the next.
@@ -10,8 +10,8 @@ from ansible.plugins.lookup import LookupBase
class LookupModule(LookupBase):
"""Exact deployed image references of every service whose ``backup.<marker>``
is truthy and that carries an ``image`` or is ``custom``-built, for baudolo's
exact ``--images-*`` matching.
equals the wanted boolean and that carries an ``image`` or is
``custom``-built, for baudolo's exact ``--images-*`` matching.
The ref is resolved via the ``image`` lookup, so it is byte-identical to the
container's ``.Config.Image`` after deploy: swarm registry prefix included,
@@ -20,8 +20,16 @@ class LookupModule(LookupBase):
non-custom shared references are skipped: their owner role carries the
image and marker.
Takes exactly one term: the backup marker key (e.g. ``no_stop_required`` or
``disabled``). Reads the live merged ``applications`` config.
Args:
terms: exactly two, the backup marker key (e.g. ``stop_required`` or
``disabled``) and the boolean the marker must equal (e.g. ``false``
for the images baudolo may copy live, ``true`` for the images it
must skip).
variables: the play variables; the live merged ``applications``
config is read through them.
Returns:
One list: the sorted, de-duplicated image references.
"""
def run(
@@ -30,11 +38,18 @@ class LookupModule(LookupBase):
variables: dict[str, Any] | None = None,
**kwargs: Any,
) -> list[list[str]]:
if not terms or len(terms) != 1:
if not terms or len(terms) != 2:
raise AnsibleError(
"backup_image requires exactly one term: the backup marker key"
"backup_image requires exactly two terms: the backup marker key "
"and the boolean it must equal"
)
marker = str(terms[0])
marker, wanted = terms
if not isinstance(wanted, bool):
raise AnsibleError(
f"backup_image: the wanted value of '{marker}' must be a boolean, "
f"got {wanted!r}"
)
marker = str(marker)
vars_ = variables or getattr(self._templar, "available_variables", {}) or {}
@@ -58,7 +73,9 @@ class LookupModule(LookupBase):
continue
for service_key, svc in services.items():
backup = svc.get("backup") if isinstance(svc, Mapping) else None
if not (isinstance(backup, Mapping) and backup.get(marker)):
if not isinstance(backup, Mapping):
continue
if backup.get(marker) is not wanted:
continue
if not (svc.get("image") or svc.get("custom")):
continue
+4 -4
View File
@@ -2,8 +2,8 @@
# Mapping logic for baudolo CLI arguments
#
# - BKP_VOLUME_2_LOCAL_DB_ROUTINE: Service names where backup.database_routine is set (for --database-containers)
# - BKP_VOLUME_2_LOCAL_NO_STOP_REQUIRED: Exact deployed image refs where backup.no_stop_required is set (for --images-no-stop-required)
# - BKP_VOLUME_2_LOCAL_DISABLED: Exact deployed image refs where backup.disabled is set (for --images-no-backup-required)
# - BKP_VOLUME_2_LOCAL_NO_STOP_REQUIRED: Exact deployed image refs where backup.stop_required is false (for --images-no-stop-required)
# - BKP_VOLUME_2_LOCAL_DISABLED: Exact deployed image refs where backup.disabled is true (for --images-no-backup-required)
# - BKP_VOLUME_2_LOCAL_HARD_RESTART: Compose project (entity) names where backup.project_hard_restart is set (for --hard-restart-projects)
# - BKP_VOLUME_2_LOCAL_SNAPSHOT_BIN: Launcher that appends --snapshot/--snapshot-subject per run when the mode allows it
# - BKP_VOLUME_2_LOCAL_SNAPSHOT_MODE: services.volume-2-local.snapshot_mode normalised; YAML reads a bare off/no/false as a boolean
@@ -51,10 +51,10 @@ BKP_VOLUME_2_LOCAL_DB_ROUTINE: >-
{{ lookup('backup_database_containers') }}
BKP_VOLUME_2_LOCAL_NO_STOP_REQUIRED: >-
{{ lookup('backup_image', 'no_stop_required') }}
{{ lookup('backup_image', 'stop_required', false) }}
BKP_VOLUME_2_LOCAL_DISABLED: >-
{{ lookup('backup_image', 'disabled') }}
{{ lookup('backup_image', 'disabled', true) }}
BKP_VOLUME_2_LOCAL_VOLUMES_DISABLED: >-
{{ lookup('backup_volume') }}
@@ -16,6 +16,7 @@ elasticsearch:
min_storage: 1066MB
backup:
database_routine: true
stop_required: true
cpus: "2.0"
mem_reservation: 2g
mem_limit: 4g
+1
View File
@@ -17,6 +17,7 @@ mariadb:
min_storage: 308MB
backup:
database_routine: true
stop_required: true
cpus: "2.0"
mem_reservation: 2g
mem_limit: 4g
+2
View File
@@ -1,5 +1,7 @@
---
openldap:
backup:
stop_required: true
modes:
compose:
enabled: true
+1
View File
@@ -19,6 +19,7 @@ postgres:
min_storage: 419MB
backup:
database_routine: true
stop_required: true
cpus: "2.0"
mem_reservation: 3g
mem_limit: 6g
+1
View File
@@ -16,6 +16,7 @@ qdrant:
min_storage: 270MB
backup:
database_routine: true
stop_required: true
cpus: "2.0"
mem_reservation: 1g
mem_limit: 2g
+1
View File
@@ -16,6 +16,7 @@ rabbitmq:
min_storage: 289MB
backup:
database_routine: true
stop_required: true
cpus: "1.0"
mem_reservation: 512m
mem_limit: 1g
+1
View File
@@ -16,6 +16,7 @@ typesense:
min_storage: 428MB
backup:
database_routine: true
stop_required: true
cpus: "1.0"
mem_reservation: 512m
mem_limit: 1g
+1 -1
View File
@@ -46,7 +46,7 @@ akaunting:
swarm:
enabled: true
backup:
no_stop_required: true
stop_required: false
image: docker.io/akaunting/akaunting
version: 3.1.21
repository: https://github.com/akaunting/docker.git
+1 -1
View File
@@ -64,7 +64,7 @@ baserow:
enabled: true
shared: true
backup:
no_stop_required: true
stop_required: false
image: baserow/baserow
version: 2.4.1
custom: true
@@ -113,6 +113,8 @@ prometheus:
# nocheck: playwright-service-flag: prebuilt upstream-compose image, mirror pre-pull only
# nocheck: dynamic-flag: fixed upstream-compose sub-service, not group-gated
bbb-web:
backup:
stop_required: true
image: alangecker/bbb-docker-web
version: "v3.0.39"
update:
@@ -123,6 +125,8 @@ bbb-web:
# nocheck: playwright-service-flag: prebuilt upstream-compose image, mirror pre-pull only
# nocheck: dynamic-flag: fixed upstream-compose sub-service, not group-gated
freeswitch:
backup:
stop_required: true
image: alangecker/bbb-docker-freeswitch
version: "v1.11.3-v3.0.39"
update:
@@ -134,6 +138,8 @@ freeswitch:
# nocheck: playwright-service-flag: prebuilt upstream-compose image, mirror pre-pull only
# nocheck: dynamic-flag: fixed upstream-compose sub-service, not group-gated
nginx:
backup:
stop_required: true
image: alangecker/bbb-docker-nginx
version: "v3.0.39-v5.4.8-1.29"
update:
@@ -157,6 +163,8 @@ bbb-shared-notes-server:
# nocheck: playwright-service-flag: prebuilt upstream-compose image, mirror pre-pull only
# nocheck: dynamic-flag: fixed upstream-compose sub-service, not group-gated
bbb-export-annotations:
backup:
stop_required: true
image: alangecker/bbb-docker-bbb-export-annotations
version: "v3.0.39"
update:
@@ -167,6 +175,8 @@ bbb-export-annotations:
# nocheck: playwright-service-flag: prebuilt upstream-compose image, mirror pre-pull only
# nocheck: dynamic-flag: fixed upstream-compose sub-service, not group-gated
webrtc-sfu:
backup:
stop_required: true
image: alangecker/bbb-docker-webrtc-sfu
version: "v2.24.0"
update:
@@ -187,6 +197,8 @@ fsesl-akka:
# nocheck: playwright-service-flag: prebuilt upstream-compose image, mirror pre-pull only
# nocheck: dynamic-flag: fixed upstream-compose sub-service, not group-gated
apps-akka:
backup:
stop_required: true
image: alangecker/bbb-docker-apps-akka
version: "v3.0.39"
update:
@@ -232,6 +244,8 @@ bbb-graphql-middleware:
# nocheck: playwright-service-flag: prebuilt upstream-compose image, mirror pre-pull only
# nocheck: dynamic-flag: fixed upstream-compose sub-service, not group-gated
periodic:
backup:
stop_required: true
image: alangecker/bbb-docker-periodic
version: "v3.0.0"
update:
@@ -242,6 +256,8 @@ periodic:
# nocheck: playwright-service-flag: prebuilt upstream-compose image, mirror pre-pull only
# nocheck: dynamic-flag: fixed upstream-compose sub-service, not group-gated
recordings:
backup:
stop_required: true
image: alangecker/bbb-docker-recordings
version: "v3.0.39"
update:
+5 -1
View File
@@ -1,5 +1,4 @@
---
# nocheck: dockerfile-custom
logout:
bond: 1
enabled: "{{ 'web-svc-logout' in group_names }}"
@@ -74,6 +73,8 @@ view:
mem_limit: 256m
pids_limit: 256
pds:
backup:
stop_required: true
image: ghcr.io/bluesky-social/pds
version: 0.4.66
min_storage: 290MB
@@ -82,9 +83,12 @@ pds:
mem_limit: 2g
pids_limit: 1024
broker:
backup:
stop_required: false
name: bluesky-broker
image: node
version: 26-alpine
custom: bluesky_broker
ports:
local:
http: 8076
@@ -36,7 +36,7 @@
args:
BLUESKY_BROKER_BASE_IMAGE: "{{ BLUESKY_BROKER_BASE_IMAGE }}"
BLUESKY_BROKER_BASE_VERSION: "{{ BLUESKY_BROKER_BASE_VERSION }}"
{{ lookup('container_image', application_id, BLUESKY_BROKER_SERVICE, image=BLUESKY_BROKER_IMAGE) }}
{{ lookup('container_image', application_id, BLUESKY_BROKER_SERVICE) }}
{{ lookup('compose_only', 'container_name', BLUESKY_BROKER_CONTAINER) }}
hostname: {{ service_name }}
{{ lookup('compose_only', 'pull_policy', 'never') }}
-1
View File
@@ -150,7 +150,6 @@ BLUESKY_FRONT_PROXY_ENDPOINTS:
BLUESKY_BROKER_BUILD_CONTEXT: "{{ [ lookup('container', application_id, 'directories.services'), 'login-broker' ] | path_join }}"
BLUESKY_BROKER_SRC_DIR: "{{ role_path }}/files/login-broker"
BLUESKY_BROKER_IMAGE: "bluesky_broker_custom"
BLUESKY_BROKER_BASE_IMAGE: "{{ lookup('config', application_id, 'services.broker.image') }}"
BLUESKY_BROKER_BASE_VERSION: "{{ lookup('config', application_id, 'services.broker.version') }}"
BLUESKY_BROKER_SERVICE: "broker"
+2 -2
View File
@@ -47,6 +47,8 @@ redis:
mem_limit: 512m
pids_limit: 512
bookwyrm:
backup:
stop_required: false
healthcheck:
flavor: curl
hostname: localhost
@@ -85,7 +87,6 @@ bookwyrm:
pids_limit: 512
migrate:
name: bookwyrm-migrate
custom: true
# nocheck: single-replica run-once bootstrap; concurrent migrate/initdb deadlock the migration graph and double-insert the SiteSettings singleton
replicas: 1
cpus: "0.5"
@@ -97,7 +98,6 @@ migrate:
# nocheck: playwright-service-flag — internal sub-component (multi-entity role)
worker:
name: bookwyrm-worker
custom: true
enabled: true # nocheck: dynamic-flag
cpus: "1.0"
mem_reservation: 256m
+1
View File
@@ -2,6 +2,7 @@
data:
type: volume
name: bookwyrm_data
backup: false
mounts:
- service: bookwyrm
target: &app_data_target /app/data
@@ -15,7 +15,7 @@
BOOKWYRM_VERSION: "{{ BOOKWYRM_VERSION }}"
BOOKWYRM_REPOSITORY: "{{ BOOKWYRM_REPOSITORY }}"
BOOKWYRM_REF: "{{ BOOKWYRM_REF }}"
{{ lookup('container_image', application_id, 'bookwyrm', version=BOOKWYRM_REF) }}
{{ lookup('container_image', application_id, 'bookwyrm') }}
{{ lookup('compose_only', 'container_name', BOOKWYRM_CONTAINER) }}
hostname: "{{ container_hostname }}"
{{ lookup('container_ports', ['bookwyrm', 'http', DOCKER_BIND_HOST]) | indent(4) }}
@@ -30,7 +30,7 @@
{% set service_name = 'worker' %}
{{ service_name }}:
{% include 'roles/sys-svc-container/templates/base.yml.j2' %}
{{ lookup('container_image', application_id, 'worker', version=BOOKWYRM_REF) }}
{{ lookup('container_image', application_id, 'bookwyrm') }}
{{ lookup('compose_only', 'container_name', BOOKWYRM_WORKER_CONTAINER) }}
command: "/venv/bin/celery -A celerywyrm worker -l INFO"
{{ lookup('compose_only', 'pull_policy', 'never') }}
@@ -45,7 +45,7 @@
{% set docker_restart_policy = 'on-failure' %}
{{ service_name }}:
{% include 'roles/sys-svc-container/templates/base.yml.j2' %}
{{ lookup('container_image', application_id, 'migrate', version=BOOKWYRM_REF) }}
{{ lookup('container_image', application_id, 'bookwyrm') }}
{{ lookup('compose_only', 'container_name', BOOKWYRM_MIGRATE_CONTAINER) }}
command: >-
bash -c '
+1 -1
View File
@@ -80,7 +80,7 @@ checkmk:
image: checkmk/check-mk-raw
version: "2.4.0p39"
backup:
no_stop_required: true
stop_required: false
name: checkmk
ports:
internal:
+1 -1
View File
@@ -35,7 +35,7 @@ chess:
name: web-app-chess
min_storage: 633MB
backup:
no_stop_required: true
stop_required: false
cpus: 0.5
mem_reservation: 256m
mem_limit: 512m
@@ -29,6 +29,8 @@ postgres:
shared: "{{ 'svc-db-postgres' in group_names }}"
# nocheck: playwright-service-flag self-provider
confluence:
backup:
stop_required: false
enabled: false
shared: true
healthcheck:
+3 -1
View File
@@ -1,5 +1,4 @@
---
# nocheck: dockerfile-custom
sso:
bond: 1
enabled: "{{ 'web-app-keycloak' in group_names }}"
@@ -27,6 +26,8 @@ postgres:
shared: "{{ 'svc-db-postgres' in group_names }}"
enabled: true # nocheck: dynamic-flag
decidim:
backup:
stop_required: false
# nocheck: architecture-pin Reason: ghcr.io/decidim/decidim publishes a single linux/amd64 manifest and upstream offers no arm64 tag, so reaching arm64 means building the Rails application from source the way web-app-pretix does, which this role does not
architectures:
- amd64
@@ -41,6 +42,7 @@ decidim:
enabled: true
image: ghcr.io/decidim/decidim
version: 0.31.6
custom: true
min_storage: 1206MB
name: decidim
cpus: "1.0"
+2
View File
@@ -2,6 +2,7 @@
uploads:
type: volume
name: decidim_uploads
backup: false
mounts:
- service: decidim
target: /app/public/uploads
@@ -9,6 +10,7 @@ uploads:
logs:
type: volume
name: decidim_logs
backup: false
mounts:
- service: decidim
target: /app/log
@@ -11,7 +11,7 @@
DECIDIM_PATCH_SCRIPT_DOCKER: "{{ DECIDIM_PATCH_SCRIPT_DOCKER }}"
DECIDIM_PATCH_RUBY_HOST_REL: "{{ DECIDIM_PATCH_RUBY_HOST_REL }}"
DECIDIM_PATCH_RUBY_DOCKER: "{{ DECIDIM_PATCH_RUBY_DOCKER }}"
{{ lookup('container_image', application_id, 'decidim', version=DECIDIM_VERSION ~ '-infinito') }}
{{ lookup('container_image', application_id, 'decidim') }}
{{ lookup('compose_only', 'container_name', DECIDIM_CONTAINER) }}
command: bash -c "until bundle exec rails db:migrate; do sleep 5; done; exec bundle exec puma -C config/puma.rb"
{{ lookup('container_ports', ['decidim', 'http', DOCKER_BIND_HOST]) | indent(4) }}
+1 -1
View File
@@ -53,7 +53,7 @@ docs:
# nocheck: min-storage-headroom Reason: the image built on the python base (1.1 GB), the English sites of the deployed working tree and of the latest commit (2.3 GB each), one translated site of each (about 2 GB each, built without _sources) and the scratch of a running build (2.4 GB); every further version or translated language opened adds about 2.3 GB
min_storage: 13GB
backup:
no_stop_required: true
stop_required: false
name: docs
ports:
internal:
+2 -2
View File
@@ -30,6 +30,8 @@ mariadb:
enabled: true # nocheck: dynamic-flag
shared: "{{ 'svc-db-mariadb' in group_names }}"
espocrm:
backup:
stop_required: false
modes:
compose:
enabled: true
@@ -67,7 +69,6 @@ daemon:
healthcheck:
test: ["CMD-SHELL", "test -f /var/www/html/bootstrap.php && php -r \"require '/var/www/html/bootstrap.php'; echo 'OK';\""]
retries: 5
custom: true
# nocheck: single-replica
replicas: 1
cpus: 0.5
@@ -75,7 +76,6 @@ daemon:
mem_limit: 0.5g
pids_limit: 384
websocket:
custom: true
# nocheck: single-replica
replicas: 1
cpus: 0.5
@@ -28,7 +28,7 @@
{% set service_name = 'daemon' %}
{{ service_name }}:
{{ lookup('container_image', application_id, 'daemon', version=ESPOCRM_VERSION) }}
{{ lookup('container_image', application_id, 'espocrm') }}
{{ lookup('compose_only', 'container_name', ESPOCRM_CONTAINER ~ '_' ~ service_name) }}
{{ lookup('compose_only', 'pull_policy', 'never') }}
init: true
@@ -45,7 +45,7 @@
{% set service_name = 'websocket' %}
{{ service_name }}:
{{ lookup('container_image', application_id, 'websocket', version=ESPOCRM_VERSION) }}
{{ lookup('container_image', application_id, 'espocrm') }}
{{ lookup('compose_only', 'container_name', ESPOCRM_CONTAINER ~ '_' ~ service_name) }}
{{ lookup('compose_only', 'pull_policy', 'never') }}
init: true
+1 -1
View File
@@ -40,7 +40,7 @@ fider:
name: fider
min_storage: 400MB
backup:
no_stop_required: true
stop_required: false
cpus: "0.5"
mem_reservation: 128m
mem_limit: 512m
+1 -1
View File
@@ -57,7 +57,7 @@ flowise:
enabled: true # nocheck: dynamic-flag
shared: true
backup:
no_stop_required: false
stop_required: true
image: node
# nocheck: docker-version
version: "24-slim"
@@ -2,6 +2,8 @@
# nocheck: seaweedfs-required, object storage not implemented for this role
# nocheck: playwright-service-flag, self-provider
friendica:
backup:
stop_required: false
healthcheck:
flavor: msmtp_curl
modes:
@@ -1,6 +1,8 @@
---
# nocheck: seaweedfs-playwright — the only objects this role writes are the branding images of tasks/01_manager.yml, and files/playwright/test-design.js fetches the sidebar logo from its bucket URL and compares it byte for byte with the configured asset; on an onion pick that fetch fails, because web-svc-seaweedfs publishes no onion vhost and the Tor-proxied browser cannot resolve its clearnet name; the document surface the shared scenario drives is the audio-library import flow, which needs a persona-owned library and a real track upload the role does not provision
funkwhale:
backup:
stop_required: false
healthcheck:
flavor: wget
modes:
@@ -33,6 +35,8 @@ funkwhale:
mem_limit: 2g
pids_limit: 1024
api:
backup:
stop_required: false
healthcheck:
flavor: curl
path: api/v1/instance/nodeinfo/2.0
@@ -57,6 +61,8 @@ migrate:
pids_limit: 512
# nocheck: image-healthcheck no internal port declared, so no probe can address it
typesense:
backup:
stop_required: false
bond: 1
enabled: true # nocheck: dynamic-flag
shared: "{{ 'svc-db-typesense' in group_names }}"
+1
View File
@@ -62,6 +62,7 @@ design_admin_template:
typesense_data:
type: volume
name: funkwhale_typesense_data
backup: false
mounts:
- service: typesense
target: /data
@@ -41,6 +41,8 @@ sso:
allowed_groups:
- "{{ lookup('rbac_group_path', application_id='web-app-fusiondirectory', role='administrator') }}"
fusiondirectory:
backup:
stop_required: false
healthcheck:
flavor: curl
modes:
@@ -3,6 +3,7 @@
data:
type: volume
name: fusiondirectory_data
backup: false
mounts:
- service: fusiondirectory
target: /assets/fusiondirectory
+1 -1
View File
@@ -53,7 +53,7 @@ gitea:
replicas: 1 # nocheck: single-replica single-writer app state on swarm-shared NFS; concurrent multi-node writers corrupt app.ini
min_storage: 270MB
backup:
no_stop_required: true
stop_required: false
name: gitea
cpus: 1.0
mem_reservation: 1g
+12
View File
@@ -75,6 +75,8 @@ gitlab:
- web-app-mailu
lifecycle: beta
webservice:
backup:
stop_required: false
image: registry.gitlab.com/gitlab-org/build/cng/gitlab-webservice-ce
version: v19.5.1
name: gitlab-webservice
@@ -91,6 +93,8 @@ webservice:
mem_limit: 6g
pids_limit: 2048
sidekiq:
backup:
stop_required: false
healthcheck:
flavor: tcp
path: liveness
@@ -105,6 +109,8 @@ sidekiq:
internal:
http: 3808
workhorse:
backup:
stop_required: false
image: registry.gitlab.com/gitlab-org/build/cng/gitlab-workhorse-ce
version: v19.5.1
name: gitlab-workhorse
@@ -115,6 +121,8 @@ workhorse:
mem_limit: 512m
pids_limit: 256
gitaly:
backup:
stop_required: true
# nocheck: single-replica
replicas: 1
# nocheck: default-placement-manager the repositories live on a node-local volume (meta/volumes.yml nfs: false, gitaly does not support NFS), which a reschedule leaves behind on the old node
@@ -132,6 +140,8 @@ gitaly:
mem_limit: 2g
pids_limit: 1024
shell:
backup:
stop_required: false
image: registry.gitlab.com/gitlab-org/build/cng/gitlab-shell
version: v19.5.1
name: gitlab-shell
@@ -143,6 +153,8 @@ shell:
mem_limit: 256m
pids_limit: 256
migrations:
backup:
stop_required: false
# nocheck: single-replica
replicas: 1
image: registry.gitlab.com/gitlab-org/build/cng/gitlab-rails-ce
+1 -1
View File
@@ -13,7 +13,7 @@ hermes:
enabled: true
shared: true
backup:
no_stop_required: true
stop_required: false
image: nousresearch/hermes-agent
version: "v2026.9.24"
name: hermes
@@ -13,7 +13,7 @@ homeassistant:
enabled: true
shared: true
backup:
no_stop_required: true
stop_required: false
image: ghcr.io/home-assistant/home-assistant
version: "2026.7"
name: homeassistant
+1 -1
View File
@@ -55,7 +55,7 @@ jellyfin:
image: jellyfin/jellyfin
version: "10.11.11"
backup:
no_stop_required: true
stop_required: false
# nocheck: single-replica Jellyfin persists all state in embedded SQLite under the shared {{ lookup('volume', 'web-app-jellyfin', 'jellyfin_config').target }} volume; concurrent replicas corrupt the database (SQLite disk I/O error, malformed image in CI) and upstream has no multi-instance support
replicas: 1
name: jellyfin
+2
View File
@@ -47,6 +47,8 @@ ldap:
shared: "{{ 'svc-db-openldap' in group_names }}"
# nocheck: playwright-service-flag self-provider
jenkins:
backup:
stop_required: true
enabled: true
shared: true
bond: 1
+2
View File
@@ -29,6 +29,8 @@ postgres:
shared: "{{ 'svc-db-postgres' in group_names }}"
# nocheck: playwright-service-flag self-provider
jira:
backup:
stop_required: true
enabled: false
shared: true
healthcheck:
+1 -1
View File
@@ -55,7 +55,7 @@ joomla:
name: joomla
min_storage: 478MB
backup:
no_stop_required: true
stop_required: false
upload:
size_mb: 100
autocreate_users: true
+4
View File
@@ -100,6 +100,8 @@ proxy:
mem_limit: 512m
pids_limit: 512
backend:
backup:
stop_required: true
# nocheck: single-replica
replicas: 1
name: kix-backend
@@ -114,6 +116,8 @@ backend:
mem_limit: 4g
pids_limit: 1024
frontend:
backup:
stop_required: true
# nocheck: single-replica
replicas: 1
name: kix-frontend
+1 -1
View File
@@ -49,7 +49,7 @@ listmonk:
image: listmonk/listmonk
version: "v6.2.0"
backup:
no_stop_required: true
stop_required: false
name: listmonk
ports:
internal:
+2 -2
View File
@@ -38,7 +38,7 @@ php:
internal:
fpm: 9000
backup:
no_stop_required: true
stop_required: false
min_storage: 660MB
cpus: "0.5"
mem_reservation: 256m
@@ -49,7 +49,7 @@ nginx:
version: "1.28"
name: magento-nginx
backup:
no_stop_required: true
stop_required: false
min_storage: 235MB
cpus: "0.5"
mem_reservation: 256m
+2
View File
@@ -157,6 +157,8 @@ antispam:
# nocheck: dynamic-flag
# nocheck: playwright-service-flag — internal sub-component
antivirus:
backup:
stop_required: false
name: mailu-antivirus
enabled: true # nocheck: dynamic-flag
shared: false
+1
View File
@@ -10,6 +10,7 @@ admin_data:
clamav_db:
type: volume
name: mailu_clamav_db
backup: false
mounts:
- service: antivirus
target: /var/lib/clamav
+1 -1
View File
@@ -50,7 +50,7 @@ mastodon:
version: v4.6.2
min_storage: 535MB
backup:
no_stop_required: true
stop_required: false
name: mastodon
cpus: "1.0"
mem_reservation: 1.5g
+1 -1
View File
@@ -37,7 +37,7 @@ matomo:
name: matomo
min_storage: 404MB
backup:
no_stop_required: true
stop_required: false
cpus: 1.0
mem_reservation: 512m
mem_limit: 1g
+3 -1
View File
@@ -98,7 +98,7 @@ synapse:
image: matrixdotorg/synapse
name: matrix-synapse
backup:
no_stop_required: true
stop_required: false
ports:
internal:
http: 8008
@@ -132,6 +132,8 @@ element:
mem_limit: 256m
pids_limit: 256
matrix-chatgpt-bot:
backup:
stop_required: false
version: 3.1.5
image: ghcr.io/matrixgpt/matrix-chatgpt-bot
min_storage: 307MB
+1 -1
View File
@@ -53,7 +53,7 @@ mattermost:
ref: v11.11.1
min_storage: 659MB
backup:
no_stop_required: true
stop_required: false
name: mattermost
cpus: "1.0"
mem_reservation: 512m
+1 -1
View File
@@ -55,7 +55,7 @@ mediawiki:
custom: true
min_storage: 546MB
backup:
no_stop_required: true
stop_required: false
name: mediawiki
ports:
local:
+2
View File
@@ -26,6 +26,8 @@ redis:
backup:
disabled: true
meta:
backup:
stop_required: false
healthcheck:
flavor: curl
modes:
+1
View File
@@ -4,6 +4,7 @@
git:
type: volume
name: meta_git
backup: false
mounts:
- service: meta
target: /var/lib/mig
+1 -1
View File
@@ -33,7 +33,7 @@ minio:
enabled: false
shared: true
backup:
no_stop_required: false
stop_required: true
image: quay.io/minio/minio
version: "RELEASE.2025-09-07T16-13-09Z" # nocheck: docker-version
name: minio
@@ -30,6 +30,8 @@ postgres:
- pg_trgm
- unaccent
mobilizon:
backup:
stop_required: false
healthcheck:
flavor: curl
modes:
+4 -1
View File
@@ -36,6 +36,8 @@ mariadb:
shared: "{{ 'svc-db-mariadb' in group_names }}"
# nocheck: playwright-service-flag: shared provider entity; the app itself is covered by this role's own Playwright spec
moodle:
backup:
stop_required: false
modes:
compose:
enabled: true
@@ -87,6 +89,8 @@ moodle:
- web-app-keycloak
lifecycle: beta
nginx:
backup:
stop_required: false
image: nginx
version: 1.31-alpine
name: moodle-nginx
@@ -100,7 +104,6 @@ nginx:
http: 80
cron:
name: moodle-cron
custom: true
min_storage: 1GB
cpus: "0.2"
mem_reservation: 128m
@@ -61,7 +61,7 @@
{{ service_name }}:
{% include 'roles/sys-svc-container/templates/deploy.yml.j2' %}
{{ lookup('compose_only', 'container_name', MOODLE_CRON_CONTAINER) }}
{{ lookup('container_image', application_id, 'cron', version=MOODLE_VERSION) }}
{{ lookup('container_image', application_id, 'moodle') }}
{{ lookup('compose_only', 'pull_policy', 'never') }}
{{ lookup('depends_on', {'moodle': 'service_healthy'}) }}
{{ lookup('container_volumes', service_name) | indent(4) }}
+1 -1
View File
@@ -73,7 +73,7 @@ n8n:
swarm:
enabled: true
backup:
no_stop_required: false
stop_required: true
image: docker.n8n.io/n8nio/n8n
version: "3.0.0"
update:
+6 -6
View File
@@ -71,7 +71,7 @@ nextcloud:
custom: true
min_storage: 553MB
backup:
no_stop_required: true
stop_required: false
cpus: "2.0"
mem_reservation: 2g
mem_limit: 3g
@@ -124,7 +124,7 @@ proxy:
image: nginx
version: 1.31.8-alpine
backup:
no_stop_required: true
stop_required: false
cpus: "0.5"
mem_reservation: 64m
mem_limit: 256m
@@ -143,7 +143,7 @@ context_agent:
image: ghcr.io/nextcloud/context_agent
version: 2.10.0
backup:
no_stop_required: true
stop_required: false
# nocheck: single-replica
replicas: 1
cpus: "1.0"
@@ -199,7 +199,7 @@ talk:
# nocheck: docker-version -- all 174 tags upstream publishes are AIO build stamps, none is a version
version: latest
backup:
no_stop_required: false
stop_required: true
turn_server:
onboard_enabled: "{{ not ( 'web-svc-coturn' in group_names ) }}"
standalone_enabled: "{{ 'web-svc-coturn' in group_names }}"
@@ -233,7 +233,7 @@ whiteboard:
version: v1.5.9
custom: nextcloud-whiteboard
backup:
no_stop_required: true
stop_required: false
cpus: "1"
mem_reservation: 128m
mem_limit: 1g
@@ -284,7 +284,7 @@ talk_recording:
# nocheck: docker-version -- all 104 tags upstream publishes are AIO build stamps, none is a version
version: latest
backup:
no_stop_required: true
stop_required: false
cpus: "2.0"
mem_reservation: 1g
mem_limit: 3g
+1 -1
View File
@@ -48,7 +48,7 @@ odoo:
mem_limit: 4g
pids_limit: 1024
backup:
no_stop_required: true
stop_required: false
email:
from_name: ERP ({{ DOMAIN_PRIMARY }})
ports:
+1 -1
View File
@@ -40,7 +40,7 @@ This role deploys OpenBao as an Infinito.Nexus application at `openbao.<domain>`
### Backup and restore
Backups run through `svc-bkp-volume-2-local` with `backup.no_stop_required: false`, so the container is quiesced for a consistent copy of the raft volume. To restore:
Backups run through `svc-bkp-volume-2-local` with `backup.stop_required: true`, so the container is quiesced for a consistent copy of the raft volume. To restore:
1. Restore the `openbao_data` volume from the backup generation.
2. Confirm the inventory still holds the original `seal_key` — a different key makes the restored store unreadable.
+1 -1
View File
@@ -59,7 +59,7 @@ openbao:
version: "2.7.2"
custom: true
backup:
no_stop_required: false
stop_required: true
# nocheck: single-replica single-node raft: a second replica would need a real raft join/bootstrap flow, and two tasks against one BoltDB directory corrupt the store
replicas: 1
name: openbao
+1 -1
View File
@@ -12,7 +12,7 @@ openclaw:
enabled: true
shared: true
backup:
no_stop_required: true
stop_required: false
image: ghcr.io/openclaw/openclaw
version: "2026.7.1"
name: openclaw
+1 -1
View File
@@ -43,7 +43,7 @@ opencloud:
# nocheck: default-placement-manager opencloud_data holds NFS-hostile engine state: NATS JetStream store (events, micro registry, posixfs id cache), bleve search index, idm.boltdb, posixfs xattr metadata; upstream says search cannot scale, so the volume must stay node-local
placement: manager
backup:
no_stop_required: true
stop_required: false
cpus: "2.0"
mem_reservation: 1g
mem_limit: 4g
+1 -2
View File
@@ -47,7 +47,7 @@ web:
version: "17"
custom: true
backup:
no_stop_required: true
stop_required: false
cpus: "3.0"
mem_reservation: 3g
mem_limit: 6g
@@ -80,7 +80,6 @@ worker:
min_storage: 5GB
proxy:
name: openproject-proxy
custom: true
cpus: "0.3"
mem_reservation: 256m
mem_limit: 512m
@@ -18,7 +18,7 @@ x-op-app: &app
{% set service_name = 'proxy' %}
{{ service_name }}:
{% include 'roles/sys-svc-container/templates/base.yml.j2' %}
{{ lookup('container_image', application_id, 'proxy', version=OPENPROJECT_VERSION) }}
{{ lookup('container_image', application_id, 'web') }}
{{ lookup('compose_only', 'container_name', OPENPROJECT_PROXY_CONTAINER) }}
{{ lookup('compose_only', 'pull_policy', 'never') }}
command: "./docker/prod/proxy"
+4 -2
View File
@@ -72,7 +72,7 @@ opentalk:
pattern: "OT_FRONTEND_IMAGE_TAG:-(v[0-9.]+)\\}"
min_storage: 234MB
backup:
no_stop_required: true
stop_required: false
cpus: "0.5"
mem_reservation: 128m
mem_limit: 512m
@@ -95,7 +95,7 @@ controller:
pattern: "OPENTALK_CONTROLLER_IMAGE_TAG:-(v[0-9.]+)\\}"
min_storage: 291MB
backup:
no_stop_required: true
stop_required: false
cpus: "1.5"
mem_reservation: 512m
mem_limit: 2g
@@ -139,6 +139,8 @@ seaweedfs:
enabled: true # nocheck: dynamic-flag
shared: "{{ 'web-svc-seaweedfs' in group_names }}"
rabbit:
backup:
stop_required: false
healthcheck:
test: ["CMD", "rabbitmq-diagnostics", "ping"]
# nocheck: healthcheck-timing-override rabbitmq-diagnostics starts an Erlang CLI node, which does not finish inside the 5s default
+1
View File
@@ -21,6 +21,7 @@ minio:
rabbit:
type: volume
name: opentalk_rabbit
backup: false
mounts:
- service: rabbit
target: /var/lib/rabbitmq
+1 -1
View File
@@ -34,7 +34,7 @@ openwebui:
enabled: true
shared: true
backup:
no_stop_required: true
stop_required: false
image: ghcr.io/open-webui/open-webui
version: 0.11.0
name: open-webui
+1 -1
View File
@@ -67,7 +67,7 @@ peertube:
live:
enabled: true
backup:
no_stop_required: true
stop_required: false
# nocheck: single-replica PeerTube has no multi-instance support upstream; the RTMP live ingest binds one instance with no VIP session affinity, and the OIDC state cookie uses a per-process key, so concurrent replicas break live streams and the auth callback
replicas: 1
cpus: 4
+4
View File
@@ -79,6 +79,8 @@ penpot:
- web-app-mailu
lifecycle: beta
frontend:
backup:
stop_required: false
image: penpotapp/frontend
version: "2.18.5"
name: penpot-frontend
@@ -87,6 +89,8 @@ frontend:
mem_limit: 512m
pids_limit: 256
backend:
backup:
stop_required: false
image: penpotapp/backend
version: "2.18.5"
name: penpot-backend
+2
View File
@@ -1,6 +1,8 @@
---
# nocheck: seaweedfs-required — object storage not implemented for this role
pgadmin:
backup:
stop_required: true
healthcheck:
flavor: wget
modes:
+2
View File
@@ -59,6 +59,8 @@ sso:
allowed_groups:
- "{{ lookup('rbac_group_path', application_id='web-app-pihole', role='administrator') }}"
pihole:
backup:
stop_required: true
healthcheck:
flavor: tcp
modes:
+1 -1
View File
@@ -53,7 +53,7 @@ pixelfed:
name: pixelfed
min_storage: 588MB
backup:
no_stop_required: true
stop_required: false
cpus: 0.75
mem_reservation: 0.5g
mem_limit: 0.75g
+1 -1
View File
@@ -66,7 +66,7 @@ pretix:
name: pretix
min_storage: 1003MB
backup:
no_stop_required: true
stop_required: false
cpus: "2.0"
mem_reservation: 1.5g
mem_limit: 3g
@@ -46,6 +46,8 @@ javascript:
shared: "{{ lookup('config', 'web-app-prometheus', 'services.sso.enabled') | bool }}"
# nocheck: playwright-service-flag — self-provider
prometheus:
backup:
stop_required: true
healthcheck:
flavor: wget
path: -/healthy
@@ -83,6 +85,8 @@ prometheus:
lifecycle: beta
min_storage: 307MB
alertmanager:
backup:
stop_required: false
healthcheck:
flavor: wget
path: -/healthy
+1 -1
View File
@@ -61,7 +61,7 @@ semaphore:
image: semaphoreui/semaphore
version: "v2.19.17"
backup:
no_stop_required: true
stop_required: false
name: semaphore
ports:
internal:
+2
View File
@@ -48,6 +48,8 @@ seaweedfs:
public: true
# nocheck: playwright-service-flag self-provider
snipe-it:
backup:
stop_required: false
healthcheck:
test: ["CMD", "wget", "-q", "-O-", "http://localhost/health"]
retries: 12
@@ -1,5 +1,7 @@
---
socialhome:
backup:
stop_required: true
healthcheck:
flavor: http_status
path: healthz
+4 -1
View File
@@ -53,6 +53,7 @@ stalwart:
name: stalwart
backup:
project_hard_restart: true
stop_required: true
migration:
import_mailu: false
mailbox_map: []
@@ -114,7 +115,7 @@ webmail:
flavor: curl
version: "1.7.5-apache"
backup:
no_stop_required: true
stop_required: false
cpus: "0.3"
mem_reservation: 256m
mem_limit: 1g
@@ -127,6 +128,8 @@ webmail:
# nocheck: dynamic-flag — role-local sub-component, always deployed with the stack
# nocheck: playwright-service-flag — antivirus milter, covered by role deploy test
clamav:
backup:
stop_required: false
enabled: true
shared: false
image: clamav/clamav-debian
+1
View File
@@ -20,6 +20,7 @@ webmail_data:
clamav_data:
type: volume
name: stalwart_clamav_data
backup: false
mounts:
- service: clamav
target: /var/lib/clamav
+2
View File
@@ -42,6 +42,8 @@ redis:
pids_limit: 256
# nocheck: playwright-service-flag — self-provider entry; test_env_services_match.py:28-32 grants the forbidden-self-gate exemption
suitecrm:
backup:
stop_required: true
healthcheck:
flavor: curl
# nocheck: healthcheck-timing-override boots slower than the ten minute window; the value predates this default and has not been measured against it
+6
View File
@@ -90,6 +90,8 @@ front:
mem_limit: 512m
pids_limit: 256
gateway:
backup:
stop_required: false
healthcheck:
flavor: http
ports:
@@ -112,6 +114,8 @@ events:
mem_limit: 512m
pids_limit: 256
async-rabbitmq:
backup:
stop_required: true
healthcheck:
test: ["CMD", "rabbitmq-diagnostics", "-q", "ping"]
retries: 5
@@ -122,6 +126,8 @@ async-rabbitmq:
mem_limit: 1.5g
pids_limit: 512
events-rabbitmq:
backup:
stop_required: true
healthcheck:
test: ["CMD", "rabbitmq-diagnostics", "-q", "ping"]
retries: 5
+1
View File
@@ -8,6 +8,7 @@ async-rabbitmq-data:
events-rabbitmq-data:
type: volume
name: taiga_events_rabbitmq_data
backup: false
mounts:
- service: events-rabbitmq
target: *var_lib_rabbitmq_target
Loaded 100 of 113 files, more files were not shown because too many files have changed in this diff. Show more