feat: homelab case study from live infra; Traefik-based deploy

- rewrote homelab (content + topology diagram + stack) from a live inspection of the host:
  Ubuntu 24.04, ~30 Docker services behind Traefik (Cloudflare-fronted, TLS, HTTP/3),
  Authentik SSO forward-auth, CrowdSec, Pi-hole, self-hosted Gitea + CI runner, socket-proxy,
  per-app network isolation; WordPress framed as being decommissioned (not future arch)
- deploy: docker-compose now uses Traefik labels + traefik_proxy network (was assumed nginx
  edge); .env.example adds SITE_HOST/TRAEFIK_ENTRYPOINT; colophon + ARCHITECTURE/DOCKER/
  DEPLOYMENT specs corrected nginx-edge -> Traefik (site container still serves via nginx)
- PROJECT_STATUS: pre-launch checklist updated; infra section added

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
cesnimda
2026-07-04 11:23:09 +02:00
parent a10418ab93
commit bfa8cfd357
8 changed files with 129 additions and 84 deletions
+24 -7
View File
@@ -1,6 +1,8 @@
# Production stack (DOCKER_SPEC §2). Publishes no host ports — the existing host
# reverse proxy routes cesnimda.co.uk -> site:8080 and /api/contact -> relay:8081
# over the shared external proxy network.
# Production stack (DOCKER_SPEC §2). Publishes no host ports — Traefik (the host's
# existing reverse proxy) discovers these containers on the shared traefik_proxy
# network via the labels below and routes cesnimda.co.uk to the site, and
# cesnimda.co.uk/api/contact to the relay. Entrypoint / cert-resolver names match
# the host Traefik convention; override via the .env values if they differ.
services:
site:
@@ -14,7 +16,14 @@ services:
- /tmp
- /var/cache/nginx
- /var/run
networks: [web]
networks: [proxy]
labels:
- traefik.enable=true
- traefik.docker.network=${PROXY_NETWORK:-traefik_proxy}
- traefik.http.routers.resumesite.rule=Host(`${SITE_HOST:-cesnimda.co.uk}`)
- traefik.http.routers.resumesite.entrypoints=${TRAEFIK_ENTRYPOINT:-websecure-external}
- traefik.http.routers.resumesite.tls=true
- traefik.http.services.resumesite.loadbalancer.server.port=8080
logging:
driver: json-file
options: { max-size: '10m', max-file: '3' }
@@ -36,12 +45,20 @@ services:
- Relay__AllowedOrigin=${RELAY_ALLOWED_ORIGIN:-https://cesnimda.co.uk}
- Relay__RateLimitPerWindow=${RELAY_RATE_LIMIT:-5}
- Relay__WindowSeconds=${RELAY_WINDOW_SECONDS:-600}
networks: [web]
networks: [proxy]
labels:
- traefik.enable=true
- traefik.docker.network=${PROXY_NETWORK:-traefik_proxy}
# More specific rule than the site router, so /api/contact wins.
- traefik.http.routers.resumerelay.rule=Host(`${SITE_HOST:-cesnimda.co.uk}`) && PathPrefix(`/api/contact`)
- traefik.http.routers.resumerelay.entrypoints=${TRAEFIK_ENTRYPOINT:-websecure-external}
- traefik.http.routers.resumerelay.tls=true
- traefik.http.services.resumerelay.loadbalancer.server.port=8081
logging:
driver: json-file
options: { max-size: '10m', max-file: '3' }
networks:
web:
proxy:
external: true
name: ${PROXY_NETWORK:-web}
name: ${PROXY_NETWORK:-traefik_proxy}