The service catalog
Services are the self-hosted building blocks of the network. They are enabled per
host, in etc/config.yaml. The host profile does not matter.
Enabling a service
Section titled “Enabling a service”Under a host’s services key, each entry enables a service. The (optional)
value customizes it:
services: immich: title: "Photos" description: "My photos & videos" domain: "photos" # service subdomain global: true # → https://photos.domain.tld (public, no zone) nextcloud: domain: "cloud" # → cloud.<zone>.domain.tld (not global) restic: # default values| Field | Role |
|---|---|
| (key) | The service to enable (e.g. immich) |
title | Name displayed on the portal |
description | Subtitle on the portal |
domain | Subdomain (default: service name). FQDN: <domain>.<zone>.domain.tld |
global | Exposes publicly via HCS: <domain>.domain.tld, without the zone (public DNS) |
icon | Portal icon |
Joining a zone service from outside
Section titled “Joining a zone service from outside”A zone service (not global) keeps its zone URL
<domain>.<zone>.domain.tld and normally only responds on the LAN, other
zones and the tailnet. Some services are additionally marked externalAccess in
the framework registry (dnf/config/modules.nix) : the HCS then publishes them
to the outside while keeping the zone URL.
Routing : internet → public DNS → HCS → (tailnet) → zone gateway → backend. The HCS terminates the public TLS certificate and relays the request to
the zone gateway, whose own vhost handles SSO
and the backend. Internal resolution is unchanged (direct to host/gateway).
| Exposing a service… | Flag | Result |
|---|---|---|
| Publicly, entire network | global: true (per service, config.yaml) | <domain>.domain.tld, no zone, served by the HCS |
| Publicly, keeping the zone URL | externalAccess (registry) | <domain>.<zone>.domain.tld, fronted by the HCS |
Catalog
Section titled “Catalog”| Category | Services |
|---|---|
| Authentication | idm (Kanidm), vaultwarden |
| Files & cloud | nextcloud, oxicloud, immich, garage, minio, nfs |
| Communication | matrix, element, jitsi-meet, turn |
| Media & leisure | jellyfin, mealie, geneweb |
| Productivity | outline, docs, searx |
| AI | ai (Open WebUI + Ollama) |
| Network | dnsmasq, adguardhome, headscale, tailscale, homepage |
| Development | forgejo, harmonia, nix-cache |
| Monitoring & backup | monitoring, loki, restic |
| System | fail2ban, postfix, printing, audio, home-assistant |
Portal and access
Section titled “Portal and access”- Portal: the
homepageservice provides a services dashboard, per zone. - Single sign-on: most services go through SSO Kanidm.
- Local or global: a service stays in its zone, unless
global: trueexposes it publicly.
Services with pinned versions
Section titled “Services with pinned versions”Some services cannot follow nixpkgs’ default version : their editor forbids skipping a major version. DNF therefore pins the package in the module, and upgrades happen one major version at a time.
| Service | Option | Upstream constraint |
|---|---|---|
idm (Kanidm) | services.kanidm.package | Only one version maintained, end of life 30 days after the release of the next one |
nextcloud | services.nextcloud.package | 33 → 34 possible, 33 → 35 impossible |
An upgrade to plan is signaled by a warning at evaluation, emitted as soon as the pinned version is deprecated. The detailed Kanidm procedure, transposable to the others, is described at the end of the
SSO and identities page.
Back up before upgrading
Section titled “Back up before upgrading”These migrations rewrite the database schema at the first startup of the new version, with no rollback. The prior backup is not a comfort precaution.
Kanidm stores in SQLite, so service stopped :
sudo systemctl stop kanidmsudo install -d -o kanidm -g kanidm /var/lib/kanidm/pre-upgradesudo cp -a /var/lib/kanidm/kanidm.db* /var/lib/kanidm/pre-upgrade/sudo kanidmd database backup /var/lib/kanidm/pre-upgrade/dump.json -c /etc/kanidm/server.tomlsudo chown -R kanidm:kanidm /var/lib/kanidmsudo systemctl start kanidmThe * is essential : the write-ahead log kanidm.db-wal survives the service shutdown and carries the latest transactions.
Nextcloud stores in PostgreSQL, so without interruption : pg_dump -Fc takes a consistent transactional snapshot on a live database.
sudo install -d -o nextcloud -g nextcloud -m 0750 /var/lib/nextcloud/pre-upgradesudo -u postgres pg_dump -Fc nextcloud > /var/lib/nextcloud/pre-upgrade/nextcloud.dumpsudo cp -a /var/lib/nextcloud/config/config.php /var/lib/nextcloud/pre-upgrade/sudo chown -R nextcloud:nextcloud /var/lib/nextcloud/pre-upgradeDo not omit config.php : it carries the installed version number, without which a restored database does not restart.