infra/roles/services/templates/traefik/dynamic/routes.yml.j2
jack 489791403c feat: migrate Outline + n8n to main server, rename S3 buckets to walava-*
- Add Outline, outline-db, outline-redis, n8n, outline-mcp containers to main docker-compose
- Add env.outline.j2 template with Resend SMTP and S3 (walava-outline bucket)
- Update Traefik routes: wiki → outline:3000, auto → n8n:5678 (local, not cross-server)
- Rename S3 buckets: visual-backup → walava-backup, visual-outline → walava-outline
- Extend backup.sh.j2: add Outline DB, n8n, Plane MinIO to backup scope
- Add outline_image, n8n_image, outline_mcp_image to services/defaults
- Remove Authelia config deployment tasks from configs.yml
- Add outline-internal and n8n-internal networks to docker-compose

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-27 03:04:54 +07:00

203 lines
5.2 KiB
Django/Jinja

# Traefik dynamic routing config — generated by Ansible
# Do not edit manually; re-run ansible-playbook deploy.yml
# ── Wildcard TLS certificate via Cloudflare DNS-01 ────────────────────────────
# One *.csrx.ru cert covers all subdomains. New services = zero cert wait.
tls:
stores:
default:
defaultGeneratedCert:
resolver: letsencrypt
domain:
main: "*.{{ domain_base }}"
sans:
- "{{ domain_base }}"
http:
routers:
traefik-dashboard:
rule: "Host(`{{ domain_traefik }}`)"
entrypoints: [websecure]
tls:
certresolver: letsencrypt
service: api@internal
middlewares: [traefik-auth, rate-limit-strict]
forgejo:
rule: "Host(`{{ domain_git }}`)"
entrypoints: [websecure]
tls:
certresolver: letsencrypt
service: forgejo
middlewares: [rate-limit-default]
plane-api:
rule: "Host(`{{ domain_plane }}`) && (PathPrefix(`/api/`) || PathPrefix(`/auth/`))"
entrypoints: [websecure]
tls:
certresolver: letsencrypt
service: plane-api
middlewares: [rate-limit-api]
plane:
rule: "Host(`{{ domain_plane }}`)"
entrypoints: [websecure]
tls:
certresolver: letsencrypt
service: plane-web
middlewares: [rate-limit-default]
plane-godmode:
rule: "Host(`{{ domain_plane }}`) && PathPrefix(`/god-mode/`)"
entrypoints: [websecure]
tls:
certresolver: letsencrypt
service: plane-admin
middlewares: [rate-limit-strict]
priority: 10
plane-spaces:
rule: "Host(`{{ domain_plane }}`) && PathPrefix(`/spaces/`)"
entrypoints: [websecure]
tls:
certresolver: letsencrypt
service: plane-space
middlewares: [rate-limit-default]
priority: 10
grafana:
rule: "Host(`{{ domain_dashboard }}`)"
entrypoints: [websecure]
tls:
certresolver: letsencrypt
service: grafana
middlewares: [rate-limit-default]
uptime-kuma:
rule: "Host(`{{ domain_status }}`)"
entrypoints: [websecure]
tls:
certresolver: letsencrypt
service: uptime-kuma
middlewares: [rate-limit-default]
walava-landing:
rule: "Host(`{{ domain_landing }}`)"
entrypoints: [websecure]
tls:
certresolver: letsencrypt
service: walava-landing
middlewares: [rate-limit-default]
wiki:
rule: "Host(`{{ domain_wiki }}`)"
entrypoints: [websecure]
tls:
certresolver: letsencrypt
service: wiki
middlewares: [rate-limit-default]
n8n:
rule: "Host(`{{ domain_n8n }}`)"
entrypoints: [websecure]
tls:
certresolver: letsencrypt
service: n8n
middlewares: [rate-limit-strict]
services:
forgejo:
loadBalancer:
servers:
- url: "http://forgejo:3000"
plane-api:
loadBalancer:
servers:
- url: "http://plane-api:8000"
plane-web:
loadBalancer:
servers:
- url: "http://plane-web:3000"
plane-admin:
loadBalancer:
servers:
- url: "http://plane-admin:80"
plane-space:
loadBalancer:
servers:
- url: "http://plane-space:3000"
grafana:
loadBalancer:
servers:
- url: "http://grafana:3000"
uptime-kuma:
loadBalancer:
servers:
- url: "http://uptime-kuma:3001"
walava-landing:
loadBalancer:
servers:
- url: "http://walava-web:80"
wiki:
loadBalancer:
servers:
- url: "http://outline:3000"
n8n:
loadBalancer:
servers:
- url: "http://n8n:5678"
middlewares:
# ── Security Headers (applied globally via entrypoint) ─────────────────
security-headers:
headers:
stsSeconds: 31536000
stsIncludeSubdomains: true
stsPreload: true
forceSTSHeader: true
frameDeny: true
contentTypeNosniff: true
browserXssFilter: true
referrerPolicy: "strict-origin-when-cross-origin"
permissionsPolicy: "camera=(), microphone=(), geolocation=(), payment=()"
customResponseHeaders:
X-Robots-Tag: "noindex, nofollow"
Server: ""
# ── Rate Limiting ──────────────────────────────────────────────────────
# Default: 100 req/s burst 50 — general web traffic
rate-limit-default:
rateLimit:
average: 100
burst: 50
period: 1s
# API: 30 req/s burst 20 — API endpoints
rate-limit-api:
rateLimit:
average: 30
burst: 20
period: 1s
# Strict: 10 req/s burst 5 — admin/login interfaces
rate-limit-strict:
rateLimit:
average: 10
burst: 5
period: 1s
# ── Auth (legacy basic auth kept for direct fallback) ─────────────────
traefik-auth:
basicAuth:
users:
- "{{ traefik_dashboard_htpasswd }}"