Skip to content

Deploy your own alpstack

alpstack is the config behind a small, self-hosted openDesk platform — Talos, Cilium, Longhorn, ArgoCD, Galera/Postgres, Keycloak, Synapse, Nextcloud, OpenProject, mail, monitoring, NetBird and Vaultwarden — sized for a family or a small organisation. This guide is for a different operator who wants to stand up the same stack on their own hardware, their own domain and their own cloud.

This is a reference architecture, not a turnkey product

alpstack is published so you can replicate it by reading and adapting — not (yet) as a parameterised product you helm install with a values file. A moderately experienced Kubernetes operator can get to a working stack from these docs; someone who has never run a cluster cannot. The couplings you'll need to replace are catalogued in What you must change, and the honest expectation is "possible without consulting us", not "trivially easy". If real adopters appear, the project may grow toward a values-driven chart family — see the roadmap.

What you get

A single GitOps-reconciled cluster running:

  • openDesk — the BMI's sovereign-workplace suite: Univention identity (Keycloak), Nextcloud (files), OpenProject, Collabora (office), Element/Synapse (chat), XWiki, and groupware mail (Open-Xchange + Postfix/Dovecot).
  • A production-grade substrate replacing openDesk's demo backing services: Galera (MariaDB), Percona PostgreSQL, Valkey, Memcached and Garage (S3) — all with off-site S3 backups.
  • Platform services — Cilium (CNI + kube-proxy replacement + host firewall), Longhorn (storage), cert-manager, Sealed Secrets, VictoriaMetrics/Logs monitoring, and Gateway-API ingress.
  • Remote access — NetBird (WireGuard mesh) and Vaultwarden.

See Architecture for how the four repos and three ArgoCD instances fit together.

What you'll need

Requirement Notes
Hosts 3 control-plane + N worker nodes (bare metal or VMs) that can boot Talos Linux. Ours run 3 CP + 6 workers; smaller works.
A DNS domain You control the zone. Many public sub-domains (id., portal., matrix., smtp.…) and an internal wildcard (*.apps.int.<domain>) are published under it.
An edge firewall Something that DNATs a fixed set of NodePorts to the workers (we use an OPNsense HA pair with CARP). See the NodePort contract.
S3-compatible object storage For Longhorn, Postgres/MariaDB and Garage off-site backups. We use Exoscale SOS; any S3 endpoint works.
A secrets vault Somewhere you keep master passwords and private keys (we use Psono). Not the cluster — the cluster only ever holds sealed secrets.
An OIDC IdP openDesk ships Keycloak, which becomes your IdP — you don't need an external one.
Ops skills Comfortable with kubectl, helm, talosctl, ArgoCD and DNS.

How this guide is organized

Read these pages in order the first time:

Page What it gives you
What you must change The complete inventory of hardcoded couplings, per repo, with file references.
Configuration values The global.* values that redirect the stack to your domain, cluster and cloud.
Secrets Every secret the stack expects, and how to seal your own set against your controller.
(this page, below) The bootstrap walkthrough.
License & contributing How alpstack is licensed and how to track upstream.

Getting started — the bootstrap walkthrough

The stack builds bottom-up in four layers. Each layer is one repo with its own bootstrap/README.md; this walkthrough is the map, and the per-repo READMEs carry the exact commands.

Fork first

Fork all four repos into your own Git host, then work on your forks. Tracking our updates later is a git merge upstream/main (see Track upstream).

0 · Prepare

  1. Pick your identifiers now and keep them in one place — you'll reuse them everywhere: cluster name, base domain, internal domain (apps.int.<domain>), S3 endpoint/region, and your Git owner. The full list is Configuration values.
  2. Provision your secrets vault and generate a master password — most of openDesk's secrets derive from it (see Secrets).

1 · Layer 1 — Talos (the OS + empty cluster)

Repo: talos-cluster. Talos is reusable out of the box; only a handful of talosctl gen config inputs are yours.

  1. Build (or reuse) a Talos image-factory schematic with the documented system extensions.
  2. talosctl gen config <your-cluster-name> https://<api-endpoint>:6443 with the repo's --config-patch @patch-*.yaml set. Edit the patches' embedded site values first — node subnet, nameserver/NTP, per-CP metrics IPs, the Dex OIDC issuer URL, and the API-server's embedded CA cert. These are itemised in What you must change → Talos.
  3. Apply configs, talosctl bootstrap, fetch the kubeconfig.

You now have an empty, encrypted, CNI-less cluster. Cilium arrives in Layer 2.

2 · Layer 2 — Platform (platform-argocd)

Repo: platform-argocd. This installs the platform ArgoCD, then Cilium, Longhorn, cert-manager (your <cluster>-ca / <cluster>-issuer), Sealed Secrets, monitoring and Gateway-API ingress via the app-of-apps pattern.

  1. Set your values/global.yaml (source-repo URL, cluster name, base/internal domains, S3 backup target).
  2. Bootstrap Sealed Secrets and seal your own platform secrets (Longhorn S3 creds, ArgoCD repo credentials, etc.) before the first sync — the committed sealed values are ours and are useless in your cluster.
  3. Bootstrap the platform ArgoCD and seed the app-of-apps (bootstrap/README.md), then watch it reconcile.

3 · Layer 3 — Addons (addons-argocd)

Repo: addons-argocd. NetBird (remote access) and Vaultwarden, plus the mail-mesh routing that publishes IMAP/SMTP over NetBird.

  1. Seal the addon secrets (NetBird PAT, Vaultwarden SSO + backup age key).
  2. The NetBird mail-routing uses manually pinned ClusterIPs, hand-rolled EndpointSlices and a server-generated Network UUID — none of which port across clusters. What you must change → Addons walks through re-pinning them for your cluster.

4 · Layer 4 — openDesk (opendesk-argocd)

Repo: opendesk-argocd. The production backing services (Galera, Percona PG, Valkey, Garage) plus a helmfile pipeline that renders the upstream openDesk charts and feeds them to ArgoCD as manifests.

  1. Set the openDesk domain/host map, Garage buckets, and the three backing-store bucket names (Configuration values).
  2. Run the generate-* script to render openDesk with your master password → sealed secrets, then sync in the documented order (the 13 databases + 13 DB users and the Keycloak realm are created by the upstream render — treat them as a set, not individual edits).

openDesk is consumed upstream, not forked

We render the upstream openDesk deployment via its own helmfile and override only what we must. You do the same — don't fork their repo. The couplings that live inside that render (DB/user names, Matrix server_name, the realm) are flagged "entwined — upstream render" throughout these docs.


Customise what you need

Not every layer is mandatory. The optional pieces:

  • NetBird / Vaultwarden (whole addons-argocd repo) — skip if you don't need a mesh VPN or a password manager. openDesk itself doesn't depend on them.
  • Mail-over-NetBird — our family reads mail only over the mesh; a normal setup can expose IMAP/SMTP through the edge firewall instead and drop the pinned-ClusterIP plumbing entirely.
  • coturn / TURN — needed only for Element calls; disable if you don't use them.
  • imapsync — a one-shot migration tool for importing existing mailboxes; delete after cutover.

Operate it

Once running, the day-to-day is the same as ours — see Operations and the Runbooks (node maintenance, storage, upgrades). Monitoring and a daily/weekly digest email come with the platform layer.

Track upstream

At reference-architecture tier the update model is fork + manual merge — the same way we consume openDesk:

git remote add upstream https://codeberg.org/alpstack/<repo>.git
git fetch upstream
git merge upstream/main      # resolve conflicts against your customisations

Your changes cluster in a few predictable places (values/global.yaml, your sealed secrets, the clusters/<name>/ overlay), so merges mostly touch chart structure, not your values. Renovate-style auto-tracking of chart bumps only becomes available if the project moves to a published-chart model.

Roadmap

This guide documents the setup well enough to replicate it. A fully parameterised, helm install-able version — with versioned chart releases you'd track via Renovate — isn't a goal today; it would only make sense if external adopters actually appear and ask for it. Everything here (the customization surface, the values schema, the secrets inventory, the license) is the groundwork that would build on.


Next: What you must change →