feat(infra): add Cloudflare fallback plan + self-hosted landing pages

Two infrastructure improvements for tech independence:

1. Cloudflare Fallback Documentation (docs/CLOUDFLARE_FALLBACK.md):
   - Plan B: WireGuard + Caddy on Hetzner VPS (€3.79/mo)
   - Complete Caddyfile with all 30+ subdomains
   - Step-by-step failover checklist (~15 min to switch)
   - Plan C: Direct IP with ISP

2. Self-Hosted Landing Pages (eliminates Cloudflare Pages dependency):
   - Nginx container (mana-infra-landings) on port 4400
   - Multi-site config: each subdomain → separate dist/ folder
   - Build script: scripts/mac-mini/build-landings.sh
   - Cloudflare Tunnel ingress rules for 10 landing page domains
   - Storage: /Volumes/ManaData/landings/ on external SSD
   - Domains: it, chats, pics, zitares, presis, clocks,
     manadeck, nutriphi, citycorners, docs

Migration path: Build landings locally, set Cloudflare DNS to
tunnel instead of Pages, then decommission CF Pages projects.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
Till JS 2026-03-24 12:07:40 +01:00
parent 954b204bac
commit e3115b302d
11 changed files with 733 additions and 27 deletions

View file

@ -87,6 +87,25 @@ services:
done
"
# Self-hosted Landing Pages (replaces Cloudflare Pages)
# Serves all Astro landing page dist/ folders via Nginx
# Build with: ./scripts/mac-mini/build-landings.sh
landings:
image: nginx:alpine
container_name: mana-infra-landings
restart: always
volumes:
- ./docker/nginx/landings.conf:/etc/nginx/conf.d/default.conf:ro
- ./docker/nginx/snippets:/etc/nginx/snippets:ro
- /Volumes/ManaData/landings:/srv/landings:ro
ports:
- "4400:80"
healthcheck:
test: ["CMD", "wget", "-q", "--spider", "http://localhost/health"]
interval: 30s
timeout: 5s
retries: 3
redis:
image: redis:7-alpine
container_name: mana-infra-redis
@ -871,9 +890,10 @@ services:
- "4080:80"
healthcheck:
test: ["CMD", "wget", "--no-verbose", "--tries=1", "--spider", "http://localhost:80/"]
interval: 120s
interval: 180s
timeout: 10s
retries: 3
start_period: 20s
matrix-web:
build:
@ -893,9 +913,10 @@ services:
- "4090:5180"
healthcheck:
test: ["CMD", "wget", "--no-verbose", "--tries=1", "--spider", "http://127.0.0.1:5180/health"]
interval: 120s
interval: 180s
timeout: 10s
retries: 3
start_period: 20s
# Matrix Bots (Ports 4010-4029)
matrix-mana-bot:
@ -932,7 +953,7 @@ services:
- "4010:4010"
healthcheck:
test: ["CMD", "wget", "--no-verbose", "--tries=1", "--spider", "http://127.0.0.1:4010/health"]
interval: 120s
interval: 300s
timeout: 10s
retries: 3
start_period: 40s
@ -961,7 +982,7 @@ services:
- "4011:4011"
healthcheck:
test: ["CMD", "wget", "--no-verbose", "--tries=1", "--spider", "http://127.0.0.1:4011/health"]
interval: 120s
interval: 300s
timeout: 10s
retries: 3
start_period: 40s
@ -1002,7 +1023,7 @@ services:
- "4012:4012"
healthcheck:
test: ["CMD", "wget", "--no-verbose", "--tries=1", "--spider", "http://127.0.0.1:4012/health"]
interval: 120s
interval: 300s
timeout: 10s
retries: 3
start_period: 40s
@ -1035,7 +1056,7 @@ services:
- "4013:4013"
healthcheck:
test: ["CMD", "wget", "--no-verbose", "--tries=1", "--spider", "http://127.0.0.1:4013/health"]
interval: 120s
interval: 300s
timeout: 10s
retries: 3
start_period: 40s
@ -1071,7 +1092,7 @@ services:
- "4014:4014"
healthcheck:
test: ["CMD", "wget", "--no-verbose", "--tries=1", "--spider", "http://127.0.0.1:4014/health"]
interval: 120s
interval: 300s
timeout: 10s
retries: 3
start_period: 40s
@ -1105,7 +1126,7 @@ services:
- "4015:4015"
healthcheck:
test: ["CMD", "wget", "--no-verbose", "--tries=1", "--spider", "http://127.0.0.1:4015/health"]
interval: 120s
interval: 300s
timeout: 10s
retries: 3
start_period: 40s
@ -1139,7 +1160,7 @@ services:
- "4016:4016"
healthcheck:
test: ["CMD", "wget", "--no-verbose", "--tries=1", "--spider", "http://127.0.0.1:4016/health"]
interval: 120s
interval: 300s
timeout: 10s
retries: 3
start_period: 40s
@ -1169,7 +1190,7 @@ services:
- "4017:4017"
healthcheck:
test: ["CMD", "wget", "--no-verbose", "--tries=1", "--spider", "http://127.0.0.1:4017/health"]
interval: 120s
interval: 300s
timeout: 10s
retries: 3
start_period: 40s
@ -1210,7 +1231,7 @@ services:
- "4018:4018"
healthcheck:
test: ["CMD", "wget", "--no-verbose", "--tries=1", "--spider", "http://127.0.0.1:4018/health"]
interval: 120s
interval: 300s
timeout: 10s
retries: 3
start_period: 40s
@ -1244,7 +1265,7 @@ services:
- "4019:4019"
healthcheck:
test: ["CMD", "wget", "--no-verbose", "--tries=1", "--spider", "http://127.0.0.1:4019/health"]
interval: 120s
interval: 300s
timeout: 10s
retries: 3
start_period: 40s
@ -1277,7 +1298,7 @@ services:
- "4021:4021"
healthcheck:
test: ["CMD", "wget", "--no-verbose", "--tries=1", "--spider", "http://127.0.0.1:4021/health"]
interval: 120s
interval: 300s
timeout: 10s
retries: 3
start_period: 40s
@ -1314,7 +1335,7 @@ services:
- "4020:4020"
healthcheck:
test: ["CMD", "wget", "--no-verbose", "--tries=1", "--spider", "http://127.0.0.1:4020/health"]
interval: 120s
interval: 300s
timeout: 10s
retries: 3
start_period: 40s
@ -1354,7 +1375,7 @@ services:
- "4022:4022"
healthcheck:
test: ["CMD", "wget", "--no-verbose", "--tries=1", "--spider", "http://127.0.0.1:4022/health"]
interval: 120s
interval: 300s
timeout: 10s
retries: 3
start_period: 40s
@ -1907,9 +1928,10 @@ services:
- "8000:8000"
healthcheck:
test: ["CMD", "wget", "--no-verbose", "--tries=1", "--spider", "http://127.0.0.1:8000/api/health"]
interval: 120s
interval: 300s
timeout: 10s
retries: 3
start_period: 30s
umami:
image: ghcr.io/umami-software/umami:postgresql-latest
@ -1927,7 +1949,7 @@ services:
- "8010:3000"
healthcheck:
test: ["CMD", "wget", "--no-verbose", "--tries=1", "--spider", "http://127.0.0.1:3000/api/heartbeat"]
interval: 120s
interval: 300s
timeout: 10s
retries: 3
start_period: 40s
@ -1956,9 +1978,10 @@ services:
- "9090:9090"
healthcheck:
test: ["CMD", "wget", "--no-verbose", "--tries=1", "--spider", "http://127.0.0.1:9090/health"]
interval: 120s
interval: 300s
timeout: 10s
retries: 3
start_period: 20s
pushgateway:
image: prom/pushgateway:v1.7.0
@ -1968,9 +1991,10 @@ services:
- "9091:9091"
healthcheck:
test: ["CMD", "wget", "--no-verbose", "--tries=1", "--spider", "http://127.0.0.1:9091/-/healthy"]
interval: 120s
interval: 300s
timeout: 10s
retries: 3
start_period: 10s
cadvisor:
image: gcr.io/cadvisor/cadvisor:v0.49.1
@ -1987,9 +2011,10 @@ services:
- "9110:8080"
healthcheck:
test: ["CMD", "wget", "--no-verbose", "--tries=1", "--spider", "http://127.0.0.1:8080/healthz"]
interval: 120s
interval: 300s
timeout: 10s
retries: 3
start_period: 20s
postgres-exporter:
image: prometheuscommunity/postgres-exporter:v0.15.0
@ -2036,9 +2061,10 @@ services:
- "9100:9100"
healthcheck:
test: ["CMD", "wget", "--no-verbose", "--tries=1", "--spider", "http://127.0.0.1:9100/metrics"]
interval: 120s
interval: 300s
timeout: 10s
retries: 3
start_period: 10s
# ============================================
# Alerting Stack (Ports 9093-9095)
@ -2067,9 +2093,10 @@ services:
- "8880:8880"
healthcheck:
test: ["CMD", "wget", "--no-verbose", "--tries=1", "--spider", "http://127.0.0.1:8880/health"]
interval: 120s
interval: 300s
timeout: 10s
retries: 3
start_period: 20s
alertmanager:
image: prom/alertmanager:v0.27.0
@ -2089,9 +2116,10 @@ services:
- "9093:9093"
healthcheck:
test: ["CMD", "wget", "--no-verbose", "--tries=1", "--spider", "http://127.0.0.1:9093/-/healthy"]
interval: 120s
interval: 300s
timeout: 10s
retries: 3
start_period: 10s
alert-notifier:
build:
@ -2109,10 +2137,10 @@ services:
- "9095:8080"
healthcheck:
test: ["CMD", "wget", "--no-verbose", "--tries=1", "--spider", "http://127.0.0.1:8080/health"]
interval: 120s
interval: 300s
timeout: 5s
retries: 3
start_period: 5s
start_period: 10s
# ============================================
# Auto-Update (Watchtower)
@ -2162,9 +2190,10 @@ services:
condition: service_healthy
healthcheck:
test: ["CMD", "python3", "-c", "import urllib.request; urllib.request.urlopen('http://localhost:8020/_health/')"]
interval: 120s
interval: 300s
timeout: 10s
retries: 3
start_period: 40s
glitchtip-worker:
image: glitchtip/glitchtip:latest
@ -2203,9 +2232,10 @@ services:
- "5100:5100"
healthcheck:
test: ["CMD", "wget", "-q", "--spider", "http://localhost:5100/"]
interval: 120s
interval: 180s
timeout: 10s
retries: 3
start_period: 20s
volumes:
redis_data: