No description
Find a file
Repository files (latest commit first)
Filename Latest commit message Latest commit date
Michael Klamminger 6bc518c7f3 invoiceninja: restrict app wud tag filter to single-digit major tags
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-16 08:04:46 +00:00
adguard add wud labels and pin watched tags to each image's version scheme 2026-10-16 07:17:28 +00:00
duin duin: fix stale NFS server IP, drop placement constraints, add README 2026-08-28 09:20:47 +00:00
forgejo forgejo: watch major-only tags for the runner image 2026-10-16 07:17:28 +00:00
invoiceninja invoiceninja: restrict app wud tag filter to single-digit major tags 2026-10-16 08:04:46 +00:00
lego add wud labels and pin watched tags to each image's version scheme 2026-10-16 07:17:28 +00:00
liwan liwan: trust Traefik's proxynet subnet so client IPs are recorded 2026-10-16 08:03:38 +00:00
nextcloud add wud labels and pin watched tags to each image's version scheme 2026-10-16 07:17:28 +00:00
ntfy add wud labels and pin watched tags to each image's version scheme 2026-10-16 07:17:28 +00:00
openproject openproject: make header SSO opt-in via OPENPROJECT_SSO_ENABLED 2026-10-16 07:17:28 +00:00
portainer add wud labels and pin watched tags to each image's version scheme 2026-10-16 07:17:28 +00:00
postgres18 add wud labels and pin watched tags to each image's version scheme 2026-10-16 07:17:28 +00:00
scheduler add wud labels and pin watched tags to each image's version scheme 2026-10-16 07:17:28 +00:00
shepherd add wud labels and pin watched tags to each image's version scheme 2026-10-16 07:17:28 +00:00
socket_proxy add socket_proxy stack for read-only Docker API access on every node 2026-10-16 07:17:28 +00:00
syncthing add wud labels and pin watched tags to each image's version scheme 2026-10-16 07:17:28 +00:00
traefik add wud labels and pin watched tags to each image's version scheme 2026-10-16 07:17:28 +00:00
uptime_kuma add wud labels and pin watched tags to each image's version scheme 2026-10-16 07:17:28 +00:00
vaultwarden add wud labels and pin watched tags to each image's version scheme 2026-10-16 07:17:28 +00:00
.gitignore Add repo overview README, deploy script, and tidy gitignore 2026-08-28 09:20:40 +00:00
deploy.sh Add repo overview README, deploy script, and tidy gitignore 2026-08-28 09:20:40 +00:00
README.md add openproject stack with Authentik header-SSO sidecar 2026-10-16 07:17:28 +00:00

docker

Docker Compose stacks deployed to a Docker Swarm cluster (self-hosted homelab/small-business infra. Each top-level directory is one independently deployable stack: <stack>/compose.yaml + <stack>/.env. There is no application code in this repo — it's infrastructure-as-config.

See each stack's own README.md for what it does, which secrets/env vars it needs, and any stack-specific notes. See CLAUDE.md for the full conventions reference (networking, secrets, volumes, deploy labels, middleware chains, etc.) used across all stacks.

Stacks

Stack Purpose
adguard Network-wide DNS ad/tracker blocking
duin Diun — watches running services for new image versions, notifies via ntfy
forgejo Forgejo Actions runner for git.m1ch.eu (pinned to l2-back1)
invoiceninja Invoice Ninja (invoicing/billing) app + MariaDB + Valkey cache
lego Let's Encrypt certificate issuance/renewal (DNS-01 via Hetzner) for Traefik
liwan Liwan — privacy-friendly web analytics
nextcloud Nextcloud + Collabora Office + Nextcloud Talk (video/chat)
ntfy ntfy — push notification server
openproject OpenProject — project management / issue tracking
portainer Portainer agent (manager nodes only)
postgres18 Shared PostgreSQL 18 database + backups + Adminer
scheduler swarm-cronjob — runs the swarm.cronjob.* labeled one-shot jobs used by other stacks
shepherd Shepherd — auto-updates services labeled shepherd.autodeploy=true
syncthing Syncthing — syncs a home folder across every swarm node (global mode)
traefik Traefik reverse proxy, Authentik forward-auth, Sablier scale-to-zero
uptime_kuma Uptime Kuma — uptime/status monitoring
vaultwarden Vaultwarden — self-hosted Bitwarden-compatible password vault

Commands

Deploy a stack

./deploy.sh <name> <stack_name>
# e.g. ./deploy.sh traefik traefik

This resolves to <name>/compose.yaml + <name>/.env, runs docker compose config to render the merged config (stripping the name: field and normalizing published:/size:/cpus: quoting so docker stack deploy accepts it), and pipes the result into docker stack deploy -c - <stack_name>.

Validate a stack before deploying

docker compose -f <name>/compose.yaml --env-file <name>/.env config

Catches syntax/interpolation errors (missing env vars, bad YAML) without touching the cluster. There is no other build/lint/test step in this repo.

Inspect what's currently running

docker service ls
docker service ps <service_name>
docker service logs <service_name> --tail 100

Dump live state of everything running on the swarm

docker service ls --format '{{.Name}}' | while read -r s; do docker service inspect "$s" > "${s}.json"; done

Used for inspection/diffing, not as a source of truth. Not git-ignored — .gitignore no longer excludes *.json, so check git status before committing anything after running this; a stray *.json dump can otherwise end up in a commit.

Secrets, configs, and .env

*/.env, *.bak, *.tmp, and tmp/ are git-ignored (as is CLAUDE.md itself). Every stack's .env holds real credentials, tokens, and domain-specific values — these files exist on disk but are never committed.

Sensitive values are passed to containers as Swarm secrets (docker secret create NAME - < value_file, referenced in compose as external: true), not as plaintext env vars. Each stack's README lists the exact secret names it expects to already exist in the swarm.

A few stacks also mount Swarm configs (docker config create NAME <file>) for larger config blobs that aren't secret — e.g. nginx vhost configs, Traefik's static file-provider config. The source files for these live at the repo root or in the stack directory (e.g. nextcloud/nginx.conf, invoiceninja/nginx.conf, traefik/compose_traefik.staticconf.yaml) and are referenced by name in the relevant README.