The compose/swarm split on `depends_on:` shape (map form with
`condition:` vs. list form, per `docker stack deploy` constraint)
was being hand-coded as a `{% if DEPLOYMENT_MODE == 'swarm' %}` gate
around every block. Repetitive, easy to forget, and templates that
did remember it had to repeat the same six-line pattern per service.
The new `depends_on` lookup encapsulates the shape switch:
{{ lookup('depends_on', {SVC: 'service_healthy', …}) }} # mapping
{{ lookup('depends_on', [SVC_A, SVC_B]) }} # all default
- Compose -> map form with explicit `condition:` per entry.
- Swarm -> list form (just names; swarm ignores depends_on
ordering semantically but accepts the syntax).
- Mapping `None` value uses the default condition (`service_started`,
matching Docker Compose's behaviour when no condition is given).
- Plain list of names uses the default for every entry.
The output is shaped so the call site reads naturally at the
service-member column:
some_service:
image: …
{{ lookup('depends_on', {DB: 'service_healthy'}) }} # at col 4
volumes: …
Concretely the lookup emits line 1 WITHOUT leading whitespace and
lines 2+ with the `indent` kwarg (default 4) plus the YAML-relative
nested indent. Jinja substitution applies the template's leading
spaces to line 1 only, so the column-4 call placement makes
`depends_on:` land at column 4 and the children at 6 / 8. Lines 2+
carry their own indent because Jinja does not propagate template-side
leading whitespace to continuation lines.
Plugin + tests:
- plugins/lookup/depends_on.py: ~190 lines. Mapping / list / empty
input handling, default_condition kwarg, condition validation
against the closed set `{service_started, service_healthy,
service_completed_successfully}`, DEPLOYMENT_MODE resolution via
templar with `mode=` test-only override, indent kwarg semantics
documented in the module docstring.
- tests/unit/plugins/lookup/test_depends_on.py: 27 cases covering
TestInputNormalisation (mapping / list / empty / typo / single
string rejection / non-string sequence rejection / unsupported
type rejection / arity errors), TestModeBehaviour (compose / swarm
/ unknown-falls-to-compose / missing-DEPLOYMENT_MODE-falls-to-compose
/ mode-kwarg override), TestOutputFormatting (line-1 unindented
exact-string assertion, indent=0 edge case, indent=6 edge case,
insertion-order stability for diff-stable output).
Lint:
- tests/lint/ansible/jinja/test_compose_template_uses_depends_on_lookup.py:
rule key `compose-depends-on-must-use-lookup`. Flags three patterns
in any `*compose*.yml.j2` under `roles/`:
1. literal `depends_on:` keyword line
2. flow-form `depends_on: [a, b]`
3. literal `condition: service_*` line
The pre-existing `lookup('container_depends_on', application_id)`
is intentionally not flagged: its call form contains no literal
`depends_on:` token in source. Scan target broadened to
`name.endswith('.yml.j2') and 'compose' in name` so
`compose.override.yml.j2` and `compose-inits.yml.j2` are covered
alongside `compose.yml.j2` and `*.compose.yml.j2`.
Migration (43 depends_on blocks across 17 templates):
- erpnext (6): configurator + backend + websocket + scheduler +
queue-short + queue-long + frontend chains.
- mailu (8): imap + smtp + oletools + antispam + antivirus + webdav +
fetchmail + webmail.
- zammad (4): rails + 3 worker shapes.
- shopware (4): web + worker + scheduler + opensearch, init-gated.
- jitsi (3): three single-key dependencies on JITSI_PROSODY_CONTAINER.
- kix (3): backend + frontend + proxy.
- bigbluebutton/compose.override.yml.j2 (2): bbb-web + etherpad,
inside the existing BBB_COLLABORA_ENABLED gate.
- moodle (2): nginx + cron, both depending on moodle.
- opentalk (2): application + recorder.
- taiga (2): events + gateway.
- matrix (1): loop-driven via `{% set deps = {} %} +
__setitem__` escape hatch over MATRIX_BRIDGES.
- matomo (1): bootstrap service.
- nextcloud (1): whiteboard sidecar.
- openproject (1): proxy.
- funkwhale (1): front.
- magento (1): nginx.
- flowise (1): postgres + redis.
Pre-existing `lookup('container_depends_on', application_id)` calls
(erpnext, nextcloud, moodle, zammad, taiga, matrix, etc.) are left
untouched -- that lookup auto-detects DB / redis from the application
config and emits its own block; it is the app-aware counterpart to
this structural lookup.
Every call placement repositioned to column 4 (standard
compose-service-member indent) so the new line-1-unindented semantic
renders correctly. Eight templates needed the column-4 reposition
(via a mechanical one-shot script that was deleted after).
`make test` green; new lint + 27 unit tests green; independent
re-grep across all `*compose*.yml.j2` finds zero residual raw
`depends_on:` / `condition:` lines.
Infinito.Nexus 🚀
🔐 One login. ♾️ Infinite applications
What is Infinito.Nexus? 📌
Infinito.Nexus is an automated, modular infrastructure framework built on Docker, Linux, and Ansible, equally suited for cloud services, local server management, and desktop workstations. At its core lies a web-based desktop with single sign-on, backed by an LDAP directory and OIDC, granting seamless access to an almost limitless portfolio of self-hosted applications. It fully supports ActivityPub applications and is Fediverse-compatible, while integrated monitoring, alerting, cleanup, self-healing, automated updates, and backup solutions provide everything an organization needs to run at scale.
| 📚 | 🔗 |
|---|---|
| 🌐 Try It Live | |
| 🔧 Request Your Setup | |
| 📖 About This Project | |
| ☕️ Support Us |
Key Features 🎯
-
Automated Deployment 📦 Turn up servers and workstations in minutes with ready-made Ansible roles.
-
Enterprise-Grade Security 🔒 Centralized user management via LDAP & OIDC (Keycloak), plus optional 2FA and encrypted storage.
-
Modular Scalability 📈 Grow from small teams to global enterprises by composing only the services you need.
-
Fediverse & ActivityPub Support 🌐 Seamlessly integrate Mastodon, Peertube, Matrix and other ActivityPub apps out of the box.
-
Self-Healing & Maintenance ⚙️ Automated cleanup, container healing, and auto-updates keep infrastructure healthy without human intervention.
-
Monitoring, Alerting & Analytics 📊 Built-in system, application, and security monitoring with multi-channel notifications.
-
Backup & Disaster Recovery 💾 Scheduled backups and scripted recovery processes to safeguard your data.
-
Continuous Updates 🔄 Automatic patching and version upgrades across the stack.
-
Application Ecosystem 🚀 A curated suite of self-hosted apps, from project management, version control, and CI/CD to chat, video conferencing, CMS, e-learning, social networking, and e-commerce, all seamlessly integrated.
Get Started 🚀
Use it online 🌐
Try Infinito.Nexus – sign up in seconds, explore the platform, and discover what our solution can do for you! 🚀🔧✨
Guides 📚
- Installation Guide for local CLI installation, Docker execution, and source builds.
- Deploy Guide for inventory creation, full deploys, and redeploy flows.
Contributing 🔨
For the full development setup, contribution workflow, testing, and coding standards, see CONTRIBUTING.md.
Invest 💹
We are actively looking for investors to help scale Infinito.Nexus and bring open, self-hosted infrastructure to more organizations worldwide. If you are interested in investing or partnering with us, please reach out via our Investor Relations contact.
Code of Conduct 🕊️
We are committed to fostering an open and welcoming environment. Please read our CODE_OF_CONDUCT.md to understand the standards we expect from all participants in our community.
Security 🛡️
For security reporting and disclosure, see SECURITY.md.
Support and Contact 💼
For expert installation, contact details, and project participation, see SUPPORT.md.
License ⚖️
Infinito.Nexus is distributed under the Infinito.Nexus Community License (Non-Commercial). Please see LICENSE.md for full terms.
