The fpm/cron occ-status healthcheck rendered a 30s start_period, far shorter
than the (image-serialized) first-boot init, so swarm killed every task with
exit 137 mid-init and the stack never converged. Give both healthchecks a 10m
start_period and raise swarm_stack_converge_retries to 600.
The nextcloud image already serializes first boot across replicas (its own
init lock), so unpin fpm from replicas: 1 and let it run on every node; keep
cron pinned as a genuine singleton. For correct multi-instance runtime, follow
the Nextcloud caching recommendation: memcache.local => APCu in both modes,
memcache.distributed and memcache.locking => Redis in swarm, backed by an
explicit redis connection array (which also fixes the RedisException at occ
upgrade, where OC\Memcache\Redis previously fell back to 127.0.0.1).
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
DEPLOYMENT_MODE is now derived per role from group membership:
swarm iff len(groups[application_id]) > 1, else compose. The cluster
infrastructure flag SWARM_CLUSTER_AVAILABLE is true whenever any host
sits in svc-docker-swarm, so DB and proxy services render attachable
overlay networks even when their own group lists only one host.
All service_is_stateful flags are removed across svc-db-mariadb,
svc-db-postgres, svc-db-openldap, svc-prx-openresty, svc-docker-registry
and svc-db-mariadb's compose template; the inventory shape now expresses
the same intent. Cluster-wide handlers (swarm build/push/validate/deploy,
external network creation, DB healthcheck) gain run_once + delegate_to
the manager so they execute exactly once regardless of how many hosts
the role's play targets. CA-injection and compose validate are gated to
compose-mode only; their compose-config strictness breaks when the
deploy block coexists with container_name under swarm.
Dead per-host swarm-resolve infrastructure is removed: swarm_resolve_
container.sh, resolve_container.yml, resolve_self.yml, the MariaDB-
specific swarm_mariadb_cid.sh, the cross-host template replication
step, and the _swarm_retries / _swarm_delay defaults. With run_once +
delegate_to: manager replacing the old "render every template on every
swarm peer" pattern, every consumer becomes a noop on workers and
collapses to the manager's one-shot path.
The web-app-nextcloud memcache override mapping flips from the legacy
"single" sentinel to "compose" (semantically equivalent under the new
model). Requirement 023 is updated to reflect the new model and drops
the now-irrelevant per-role opt-out / placement-constraint clauses.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>