Implemented all service roles

- docker: install Docker Engine from official apt repo, configure log rotation,
  create shared traefik_public network
- traefik: reverse proxy with automatic Let's Encrypt TLS, dashboard on
  cloud.ladkau.de behind basic auth
- gitea: self-hosted Git with PostgreSQL, Git-over-SSH on port 2222
- sso: Keycloak with PostgreSQL for OIDC/OAuth2 single sign-on
- nextcloud: file storage with PostgreSQL, Redis, cron sidecar, CalDAV/CardDAV
  well-known redirects
- mail: Roundcube webmail client with PostgreSQL
- registry: Docker Registry v2 with htpasswd auth, no upload size limit
- k8s: placeholder nginx page

All secrets documented in vault.yml; runbook updated with per-service
first-run notes.
This commit is contained in:
ml
2026-06-27 15:35:15 +02:00
parent 6115d9d48f
commit 75a0f21f74
30 changed files with 979 additions and 10 deletions
@@ -0,0 +1,29 @@
# Managed by Ansible — do not edit manually
services:
registry:
image: registry:2
container_name: registry
restart: unless-stopped
environment:
REGISTRY_AUTH: htpasswd
REGISTRY_AUTH_HTPASSWD_REALM: Container Registry
REGISTRY_AUTH_HTPASSWD_PATH: /auth/htpasswd
REGISTRY_STORAGE_DELETE_ENABLED: "true"
volumes:
- {{ registry_data_dir }}/data:/var/lib/registry
- {{ registry_data_dir }}/auth:/auth:ro
networks:
- traefik_public
labels:
- "traefik.enable=true"
- "traefik.http.routers.registry.rule=Host(`{{ domain_registry }}`)"
- "traefik.http.routers.registry.entrypoints=websecure"
- "traefik.http.routers.registry.tls.certresolver=letsencrypt"
- "traefik.http.services.registry.loadbalancer.server.port=5000"
- "traefik.http.routers.registry.middlewares=registry-buffering"
# Remove body size limit so large image layers can be pushed
- "traefik.http.middlewares.registry-buffering.buffering.maxRequestBodyBytes=0"
networks:
traefik_public:
external: true