--- sso: bond: 1 enabled: "{{ 'web-app-keycloak' in group_names }}" shared: "{{ 'web-app-keycloak' in group_names }}" flavor: oidc oidc: plugin: "" # nocheck: playwright-service-flag: infrastructural sub-component (TURN/STUN) coturn: bond: 1 enabled: "{{ 'web-svc-coturn' in group_names }}" shared: "{{ 'web-svc-coturn' in group_names }}" logout: bond: 1 enabled: "{{ 'web-svc-logout' in group_names }}" shared: "{{ 'web-svc-logout' in group_names }}" ldap: bond: 1 enabled: "{{ 'svc-db-openldap' in group_names }}" shared: "{{ 'svc-db-openldap' in group_names }}" dashboard: bond: 1 enabled: "{{ 'web-app-dashboard' in group_names }}" shared: "{{ 'web-app-dashboard' in group_names }}" matomo: bond: 1 enabled: "{{ 'web-app-matomo' in group_names }}" shared: "{{ 'web-app-matomo' in group_names }}" email: bond: 1 enabled: "{{ MAIL_PROVIDER in group_names }}" shared: "{{ MAIL_PROVIDER in group_names }}" # nocheck: shared # nocheck: dynamic-flag # nocheck: playwright-service-flag: DB engine, covered by role-local integration tests redis: bond: 1 backup: disabled: true enabled: true # nocheck: dynamic-flag shared: "{{ 'svc-db-redis' in group_names }}" cpus: "1" mem_reservation: 256m mem_limit: 1g pids_limit: 512 name: "{{ 'web-app-nextcloud' | get_entity_name }}-redis" # nocheck: playwright-service-flag: DB engine, covered by role-local integration tests mariadb: bond: 1 enabled: true # nocheck: dynamic-flag shared: "{{ 'svc-db-mariadb' in group_names }}" cpus: "0.75" mem_reservation: 512m mem_limit: 1.5g pids_limit: 512 # nocheck: playwright-service-flag self-provider nextcloud: enabled: true shared: true bond: 1 modes: compose: enabled: true swarm: enabled: true name: nextcloud image: nextcloud # nocheck: docker-version integration_openproject v3.2.0 caps at Nextcloud 34; only its v3.3.0 nightlies declare 35, lift once 3.3.0 is stable version: 34-fpm-alpine custom: true min_storage: 553MB backup: no_stop_required: true cpus: "2.0" mem_reservation: 2g mem_limit: 3g pids_limit: 512 # danger: lifts Nextcloud's SSRF guard for EVERY outbound client -- federated shares, # external storage, webcal, previews -- and Nextcloud offers no per-host allowlist. allow_local_remote_servers: enabled: "{{ ((ENVIRONMENT | lower) == 'development') | lower }}" default_quota: "1000000000" legacy_login_mask: enabled: "{{ not (lookup('config', 'web-app-nextcloud', 'services.sso.enabled') | bool) }}" performance: php: upload_limit: 5G fpm: max_children: 16 start_servers: 4 min_spare_servers: 4 max_spare_servers: 8 request_terminate_timeout: 900s plugins_enabled: true proxy: service_key: proxy ports: local: http: 8001 internal: http: 80 fpm: 9000 public: stun_turn: 3480 stun_turn_tls: 5350 relay: start: 50000 end: 59999 run_after: - web-app-keycloak - web-app-matomo - web-app-gitlab - web-app-mattermost - web-app-openproject - web-app-zammad lifecycle: beta proxy: name: nextcloud-proxy healthcheck: flavor: curl # nocheck: healthcheck-timing-override a sidecar of a stack whose main service alone takes minutes; the value predates this default and has not been measured against it start_period: 20m image: nginx version: 1.31.8-alpine backup: no_stop_required: true cpus: "0.5" mem_reservation: 64m mem_limit: 256m pids_limit: 512 min_storage: 226MB ports: internal: http: 80 # nocheck: playwright-service-flag # nocheck: dynamic-flag the container serves this role's MCP surface, so it tracks the role's own mcp flag rather than one client's presence context_agent: bond: 1 enabled: "{{ lookup('config', 'web-app-nextcloud', 'mcp.enabled') | bool }}" shared: "{{ lookup('config', 'web-app-nextcloud', 'mcp.enabled') | bool }}" name: nextcloud-context-agent image: ghcr.io/nextcloud/context_agent version: 2.10.0 backup: no_stop_required: true # nocheck: single-replica replicas: 1 cpus: "1.0" mem_reservation: 512m mem_limit: 1g pids_limit: 512 min_storage: 512MB ports: internal: http: 23000 healthcheck: flavor: http_status path: heartbeat # nocheck: healthcheck-timing-override a sidecar of a stack whose main service alone takes minutes; the value predates this default and has not been measured against it start_period: 20m # nocheck: playwright-service-flag MCP sidecar, no browser surface # nocheck: dynamic-flag the sidecar fronts this role's MCP surface, so it tracks the role's own mcp flag rather than one client's presence contextagentmcp: enabled: "{{ lookup('config', 'web-app-nextcloud', 'mcp.enabled') | bool }}" shared: false image: python # nocheck: docker-version base of the self-built stdlib adapter, not the served application version: "3.13.15-slim" custom: true name: contextagentmcp cpus: "0.25" mem_reservation: 16m mem_limit: 24m pids_limit: 64 healthcheck: flavor: http_status path: health ports: internal: http: 8080 cron: # nocheck: single-replica singleton cron.sh; replicas double-run background jobs on the shared data volume replicas: 1 name: nextcloud-cron cpus: "0.25" mem_reservation: 128m mem_limit: 512m pids_limit: 256 min_storage: 1GB # nocheck: dynamic-flag # nocheck: playwright-service-flag: infrastructural sub-component (real-time communication) talk: bond: 1 enabled: "{{ 'web-svc-coturn' in group_names }}" shared: "{{ 'web-svc-coturn' in group_names }}" name: nextcloud-talk image: nextcloud/aio-talk # nocheck: docker-version -- all 174 tags upstream publishes are AIO build stamps, none is a version version: latest backup: no_stop_required: false turn_server: onboard_enabled: "{{ not ( 'web-svc-coturn' in group_names ) }}" standalone_enabled: "{{ 'web-svc-coturn' in group_names }}" network_mode: bridge cpus: "2.0" mem_reservation: 1g mem_limit: 2g pids_limit: 1024 min_storage: 274MB ports: internal: signaling: 8081 healthcheck: flavor: tcp port_key: signaling # nocheck: healthcheck-timing-override a sidecar of a stack whose main service alone takes minutes; the value predates this default and has not been measured against it start_period: 20m whiteboard: name: nextcloud-whiteboard image: ghcr.io/nextcloud-releases/whiteboard version: v1.5.9 custom: nextcloud-whiteboard backup: no_stop_required: true cpus: "1" mem_reservation: 128m mem_limit: 1g pids_limit: 1024 min_storage: 683MB ports: internal: http: 3002 healthcheck: flavor: nc # nocheck: healthcheck-timing-override a sidecar of a stack whose main service alone takes minutes; the value predates this default and has not been measured against it start_period: 20m # nocheck: playwright-service-flag: infrastructural sub-component (collaborative editing) onlyoffice: bond: 0.5 enabled: "{{ 'web-svc-onlyoffice' in group_names }}" shared: "{{ 'web-svc-onlyoffice' in group_names }}" # nocheck: playwright-service-flag: infrastructural sub-component (collaborative editing) collabora: bond: 1 enabled: "{{ 'web-svc-collabora' in group_names }}" shared: "{{ 'web-svc-collabora' in group_names }}" # nocheck: playwright-service-flag: bridged web-conferencing partner, covered by partner role spec bigbluebutton: bond: 0.5 enabled: "{{ 'web-app-bigbluebutton' in group_names }}" shared: "{{ 'web-app-bigbluebutton' in group_names }}" # nocheck: playwright-service-flag: bridged wiki partner, covered by partner role spec xwiki: bond: 0.5 enabled: "{{ 'web-app-xwiki' in group_names }}" shared: "{{ 'web-app-xwiki' in group_names }}" # nocheck: playwright-service-flag: object store, no Playwright surface minio: enabled: false # nocheck: dynamic-flag shared: false # nocheck: dynamic-flag seaweedfs: bond: 1 enabled: "{{ 'web-app-seaweedfs' in group_names }}" shared: "{{ 'web-app-seaweedfs' in group_names }}" # nocheck: playwright-service-flag internal recording server, reachable only from the Talk signaling backend # nocheck: dynamic-flag the recording server is part of the Talk deployment, so it follows the talk entry rather than a role's presence talk_recording: enabled: "{{ lookup('config', 'web-app-nextcloud', 'services.talk.enabled') | bool }}" shared: false name: nextcloud-talk-recording image: nextcloud/aio-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 cpus: "2.0" mem_reservation: 1g mem_limit: 3g pids_limit: 1024 min_storage: 507MB ports: internal: recording: 1234 # nocheck: playwright-service-flag: verified by web-svc-css provider spec css: bond: 1 enabled: "{{ 'web-svc-css' in group_names }}" shared: "{{ 'web-svc-css' in group_names }}" # nocheck: dynamic-flag # nocheck: playwright-service-flag: captcha backend, infrastructural hcaptcha: enabled: "{{ HCAPTCHA_ENABLED | bool }}" prometheus: bond: 1 enabled: "{{ 'web-app-prometheus' in group_names }}" shared: "{{ 'web-app-prometheus' in group_names }}" # nocheck: playwright-service-flag tor: bond: 0.5 enabled: "{{ 'svc-net-tor' in group_names }}" shared: true # nocheck: dynamic-flag # nocheck: playwright-service-flag: bridged openproject partner, covered by partner role spec openproject: bond: 0.5 enabled: "{{ 'web-app-openproject' in group_names }}" shared: "{{ 'web-app-openproject' in group_names }}" # nocheck: playwright-service-flag: bridged gitlab partner, covered by partner role spec gitlab: bond: 0.5 enabled: "{{ 'web-app-gitlab' in group_names }}" shared: "{{ 'web-app-gitlab' in group_names }}" # nocheck: playwright-service-flag: bridged discourse partner, covered by partner role spec discourse: bond: 0.3 enabled: "{{ 'web-app-discourse' in group_names }}" shared: "{{ 'web-app-discourse' in group_names }}" # nocheck: playwright-service-flag: bridged mattermost partner, covered by partner role spec mattermost: bond: 0.5 enabled: "{{ 'web-app-mattermost' in group_names }}" shared: "{{ 'web-app-mattermost' in group_names }}" # nocheck: playwright-service-flag: bridged matrix partner, covered by partner role spec matrix: bond: 0.5 enabled: "{{ 'web-app-matrix' in group_names }}" shared: "{{ 'web-app-matrix' in group_names }}" # nocheck: playwright-service-flag: bridged zammad partner, covered by partner role spec zammad: bond: 0.5 enabled: "{{ 'web-app-zammad' in group_names }}" shared: "{{ 'web-app-zammad' in group_names }}" # nocheck: playwright-service-flag: bridged openwebui partner, covered by partner role spec openwebui: bond: 0.5 enabled: "{{ 'web-app-openwebui' in group_names }}" shared: "{{ 'web-app-openwebui' in group_names }}" # nocheck: playwright-service-flag, dynamic-flag - bridged litellm gateway partner, covered by partner role spec, and a single shared instance litellm: bond: 0.5 enabled: "{{ LITELLM_USABLE }}" shared: true # nocheck: playwright-service-flag: bridged mastodon partner, covered by partner role spec mastodon: bond: 0.5 enabled: "{{ 'web-app-mastodon' in group_names }}" shared: "{{ 'web-app-mastodon' in group_names }}" # nocheck: playwright-service-flag: bridged peertube partner, covered by partner role spec peertube: bond: 0.5 enabled: "{{ 'web-app-peertube' in group_names }}" shared: "{{ 'web-app-peertube' in group_names }}" # TODO(bridge): no nc-33-compatible integration_moodle on the app store (absent for nc 30/32/33). # Re-enable enabled/shared (back to the "web-app-moodle in group_names" form) once a plugin ships. # nocheck: playwright-service-flag: bridged moodle partner, covered by partner role spec moodle: enabled: false # nocheck: dynamic-flag shared: false # nocheck: dynamic-flag # TODO(bridge): integration_suitecrm requires nc <= 24 (see meta/addons/integration_suitecrm.yml). # Re-enable enabled/shared (back to the "web-app-suitecrm in group_names" form) once a plugin ships. # nocheck: playwright-service-flag: bridged suitecrm partner, covered by partner role spec suitecrm: enabled: false # nocheck: dynamic-flag shared: false # nocheck: dynamic-flag # nocheck: dynamic-flag # nocheck: playwright-service-flag, dynamic-flag infrastructure backup consumer container_backup: # nocheck: bond-baseline backup host joins outside the variant topology bond: 1 enabled: "{{ 'svc-bkp-volume-2-local' in group_names }}" shared: true # nocheck: playwright-service-flag: MCP pairing is proven by the role's own MCP spec, not by a per-consumer gate hermes: bond: 0.5 enabled: "{{ 'web-app-hermes' in group_names }}" shared: "{{ 'web-app-hermes' in group_names }}" # nocheck: playwright-service-flag: MCP pairing is proven by the role's own MCP spec, not by a per-consumer gate openclaw: bond: 0.5 enabled: "{{ 'web-app-openclaw' in group_names }}" shared: "{{ 'web-app-openclaw' in group_names }}" # nocheck: playwright-service-flag: MCP pairing is proven by the role's own MCP spec, not by a per-consumer gate # nocheck: dynamic-flag the entry refuses this client, so the link is off on every host and no group_names gate can decide it flowise: enabled: false shared: false mcp_consumer: false