Files
homelab/README.md
T
forust 5c8bc15e60
renovate-ci / validate-renovate (push) Skipped
ci / lint-compose (push) Successful in 10s
ci / lint-actionlint (push) Successful in 7s
ci / lint-shellcheck (push) Successful in 9s
ci / lint-prettier (push) Successful in 19s
ci / lint-ruff (push) Successful in 7s
ci / lint-yaml (push) Successful in 10s
ci / lint-dockerfiles (push) Successful in 6s
ci / validate (push) Successful in 6s
ci / build (push) Skipped
ci / lint-compose (pull_request) Successful in 10s
ci / lint-actionlint (pull_request) Successful in 5s
ci / lint-shellcheck (pull_request) Successful in 8s
ci / lint-prettier (pull_request) Successful in 16s
ci / lint-ruff (pull_request) Successful in 7s
ci / lint-yaml (pull_request) Successful in 10s
ci / lint-dockerfiles (pull_request) Successful in 7s
ci / validate (pull_request) Successful in 7s
ci / build (pull_request) Skipped
renovate-ci / validate-renovate (pull_request) Successful in 9s
docs(reloader): describe workload opt-in and reload policy
2026-10-06 16:14:04 +02:00

9.8 KiB

Homelab

Configuration for my homelab: Kubernetes manifests, Docker Compose stacks, and the Gitea Actions that build and deploy them. Most applications have both deployment formats. Headscale, Nextcloud AIO, and the media stack run on Docker; Kubernetes provides their ingress through Services and EndpointSlices.

These files contain this lab's domains, IP addresses, storage paths, and private registry names. Running them on another machine takes some editing.

Start here

What gets deployed

The active files are switches for the deploy workflow, not health indicators.

File Effect
<service>/active Include that directory's compose.yaml or compose.yml.
<service>/k8s/active Include its Kubernetes manifests or Kustomize overlay.
Both Run the Compose stack and apply the Kubernetes resources.
Neither Keep the configuration in Git without automatic deployment.

shared-compose.yaml, client.compose.yaml, and renovate-compose.yaml are manual entry points. The deploy script does not discover them.

Kubernetes selection excludes secret files, examples, Helm values, and patches. Helm releases listed in deploy-lib.sh are upgraded separately. Traefik, cert-manager, and CrowdSec have additional bootstrap steps; an active marker does not install their charts.

The table below describes committed configuration. It does not claim that a service is currently healthy or running.

Services

Service Configuration Selected by markers
AdGuard Home Kubernetes + Compose Kubernetes
Authentik Kubernetes + Compose Kubernetes
cert-manager Kubernetes / Helm Manual
Cloudflare DDNS Kubernetes + Compose Kubernetes
Checkmk Kubernetes + Compose Manual
Cloudflare Tunnel Kubernetes / Helm Manual
File converters Kubernetes + Compose Kubernetes
CrowdSec Kubernetes / Helm Manual
Dockmon Kubernetes + Compose Manual
Downtify Kubernetes + Compose Manual
EDU session keeper and Telegram bot Kubernetes + Compose Kubernetes
Error pages Kubernetes + Compose Kubernetes
Gitea Kubernetes + Compose Kubernetes
Glance Kubernetes + Compose Manual
Headscale Compose + Kubernetes routing Compose, Kubernetes
Homarr Kubernetes + Compose Manual
Homepages Kubernetes + Compose Kubernetes
Immich Kubernetes + Compose Kubernetes
Kener Kubernetes + Compose Manual
Loki and Alloy Kubernetes / Helm Kubernetes
MeTube Kubernetes + Compose Kubernetes
n8n Kubernetes + Compose Manual
NetBird Kubernetes + Compose Kubernetes
NetBox Kubernetes + Compose Kubernetes
Netronome Kubernetes + Compose Kubernetes
Nextcloud AIO Compose + Kubernetes routing Compose, Kubernetes
Penpot Compose Manual
Portainer Kubernetes + Compose Manual
Shared PostgreSQL Kubernetes + Compose Kubernetes
Monitoring stack Kubernetes + Compose Kubernetes
RackPeek Kubernetes + Compose Kubernetes
Reloader Kubernetes / Helm Kubernetes
Renovate Kubernetes + Compose Kubernetes
SearXNG Kubernetes + Compose Manual
Media stack Compose + Kubernetes routing Compose, Kubernetes
Termix Kubernetes + Compose Manual
Traefik Kubernetes + Compose Kubernetes
Uptime Kuma Kubernetes + Compose Kubernetes
Vaultwarden Kubernetes + Compose Kubernetes
3x-ui Kubernetes Kubernetes

Running a Compose stack

Use the service README first. Where a service has an env example, copy it inside that service's directory and replace the placeholders. The root .env.example is an older collection of variables, not a complete configuration for every stack.

For example, from the repository root:

cd netbox
cp .env.example .env
$EDITOR .env
docker compose config --quiet
docker compose up -d
docker compose ps

Stacks that attach to proxy require an existing Docker network of that name and an appropriate reverse proxy. Published host ports still work independently of Traefik. Check port conflicts before starting an alternative to a Kubernetes service: DNS, STUN, and HTTP listeners can share the same host.

docker compose down keeps named volumes. Adding -v removes them.

Preparing Kubernetes

The manifests assume Traefik CRDs, cert-manager, and a working storage provisioner. PrometheusRule and ServiceMonitor resources also need the Prometheus Operator. Replace the lab's hosts and addresses before using the configuration elsewhere.

Create a service's namespace, then prepare its ignored Secret from the example. For example:

kubectl apply -f netbox/k8s/namespace.yaml
cp netbox/k8s/secrets.yaml.example netbox/k8s/secrets.yaml
$EDITOR netbox/k8s/secrets.yaml
kubectl apply -f netbox/k8s/secrets.yaml

The deploy workflow applies the tracked resources for marked services. Avoid applying an entire k8s/ directory blindly: some directories contain Helm values, examples, and alternative routes. For a manual change, apply the selected manifest explicitly and check the resulting rollout.

Shared database passwords must agree between the database namespace and each application's Secret. Updating the PostgreSQL Secret does not change an existing role's password; see the database README.

Local checks

CI pins its tools in .gitea/workflows/tool-versions.env. Use the same versions:

tools_dir="$(bash .gitea/workflows/install-ci-tools.sh)"
export PATH="$tools_dir:$PATH"
ruff check .
ruff format --check .
actionlint -config-file .gitea/actionlint.yaml .gitea/workflows/*.yaml
.gitea/workflows/sync-renovate-configmap.sh --check

The workflow README lists the rest of the checks. Structure checks do not establish that local Secrets, mounted files, storage, or external services are ready.

Data and recovery

State lives outside Git: PVCs, Docker volumes, bind mounts, databases, and ignored configuration. Keep backups of application data and the keys needed to read it. An image rollback does not roll back database migrations or ConfigMap contents.

Many PVCs use the cluster's default StorageClass; monitoring explicitly uses local-path. Check the PV reclaim policy before deleting a PVC or namespace. The manifests do not provide a repository-wide backup schedule.

incident-archive/ contains past incident notes. .docs/storage-audit-instruction.md is a planning document, not evidence that NFS has been installed.