# ------------------------------------------------------------------- # Global options # ------------------------------------------------------------------- { grace_period 15s # Admin API слушает только loopback контейнера: на :2019 его видела бы вся # web_proxy_network, и любое приложение могло бы переписать маршрутизацию # или снять forward_auth. Метрики вынесены в отдельный site-блок ниже, и # порт у него другой: сайт на :2019 перехватывал бы IPv6-петлю (admin висит # только на IPv4), и `caddy reload` молча ничего не применял бы. admin localhost:2019 # Enable metrics in Prometheus format # https://caddyserver.com/docs/metrics metrics } # ------------------------------------------------------------------- # Metrics # ------------------------------------------------------------------- # Prometheus-метрики для netdata (files/netdata/go.d/prometheus.conf). # Наружу порт не публикуется — доступен только внутри web_proxy_network. http://:2020 { metrics /metrics } # ------------------------------------------------------------------- # Snippets # ------------------------------------------------------------------- # Общие настройки всех сайтов: access-лог и HSTS. # # Лог общий для всех сайтов, его разбирает GoAccess. Mode 644 нужен, чтобы # файл читали потребители на хосте (goaccess и ad-hoc tail): lumberjack иначе # ставит 0600. (common) { log { output file /var/log/caddy/access.log { mode 644 roll_size 100mib roll_keep 10 roll_keep_for 720h } format json } # HSTS: браузер, однажды увидевший заголовок, целый год ходит на это имя только # по https, минуя редирект с http, — закрывает downgrade и SSL-strip. # Без includeSubDomains: политика по каждому имени своя, а под vakhrushev.me # есть поддомены не с этого сервера (например photo.vakhrushev.me). header Strict-Transport-Security "max-age=31536000" } # ------------------------------------------------------------------- # Applications # ------------------------------------------------------------------- vakhrushev.me { tls anwinged@ya.ru import common # Matrix federation delegation: tells other servers/clients that the # homeserver for vakhrushev.me lives at matrix.vakhrushev.me. # https://spec.matrix.org/latest/server-server-api/#server-discovery handle /.well-known/matrix/server { header Content-Type application/json header Access-Control-Allow-Origin * respond `{"m.server": "matrix.vakhrushev.me:443"}` } handle /.well-known/matrix/client { header Content-Type application/json header Access-Control-Allow-Origin * respond `{"m.homeserver": {"base_url": "https://matrix.vakhrushev.me"}}` } handle { reverse_proxy { to homepage_app:80 } } } # Дашборд со списком сервисов (gethomepage). Закрыт за Authelia. Это отдельный # сервис, не путать с кастомной домашней страничкой homepage_app на apex выше. start.vakhrushev.me { tls anwinged@ya.ru import common forward_auth authelia_app:9091 { uri /api/authz/forward-auth copy_headers Remote-User Remote-Groups Remote-Email Remote-Name } reverse_proxy { to dashboard_app:3000 } } matrix.vakhrushev.me { tls anwinged@ya.ru import common reverse_proxy { to tuwunel_app:6167 } } auth.vakhrushev.me { tls anwinged@ya.ru import common reverse_proxy authelia_app:9091 } status.vakhrushev.me { tls anwinged@ya.ru import common forward_auth authelia_app:9091 { uri /api/authz/forward-auth copy_headers Remote-User Remote-Groups Remote-Email Remote-Name } reverse_proxy netdata:19999 } git.vakhrushev.me { tls anwinged@ya.ru import common reverse_proxy { to gitea_app:3000 } } outline.vakhrushev.me { tls anwinged@ya.ru import common reverse_proxy { to outline_app:3000 } } gramps.vakhrushev.me { tls anwinged@ya.ru import common reverse_proxy { to gramps_app:5000 } } miniflux.vakhrushev.me { tls anwinged@ya.ru import common # /metrics наружу не отдаём. METRICS_ALLOWED_NETWORKS тут не помогает: за # прокси Miniflux видит приватный IP контейнера Caddy, а не адрес клиента. # Netdata скрейпит miniflux_app:8080/metrics напрямую по докер-сети, мимо Caddy. handle /metrics { respond 404 } handle { reverse_proxy { to miniflux_app:8080 } } } wakapi.vakhrushev.me { tls anwinged@ya.ru import common reverse_proxy { to wakapi_app:3000 } } wanderer.vakhrushev.me { tls anwinged@ya.ru import common reverse_proxy { to wanderer_web:3000 } } memos.vakhrushev.me { tls anwinged@ya.ru import common reverse_proxy { to memos_app:5230 } } # tududi сам логинит пользователей через OIDC (Authelia), поэтому здесь без # forward_auth — иначе двойная аутентификация. tududi.vakhrushev.me { tls anwinged@ya.ru import common reverse_proxy { to tududi_app:3002 } } remembos.vakhrushev.me { tls anwinged@ya.ru import common forward_auth authelia_app:9091 { uri /api/authz/forward-auth copy_headers Remote-User Remote-Groups Remote-Email Remote-Name } reverse_proxy { to remembos_app:8080 } } calibre.vakhrushev.me { tls anwinged@ya.ru import common reverse_proxy { to calibre_web_app:8083 } } wanderbase.vakhrushev.me { tls anwinged@ya.ru import common forward_auth authelia_app:9091 { uri /api/authz/forward-auth copy_headers Remote-User Remote-Groups Remote-Email Remote-Name } reverse_proxy { to wanderer_db:8090 } } rssbridge.vakhrushev.me { tls anwinged@ya.ru import common forward_auth authelia_app:9091 { uri /api/authz/forward-auth copy_headers Remote-User Remote-Groups Remote-Email Remote-Name } reverse_proxy { to rssbridge_app:80 } } dozzle.vakhrushev.me { tls anwinged@ya.ru import common forward_auth authelia_app:9091 { uri /api/authz/forward-auth copy_headers Remote-User Remote-Groups Remote-Email Remote-Name Remote-Filter } reverse_proxy dozzle_app:8080 } # GoatCounter — веб-аналитика посещений. Один инстанс обслуживает несколько # сайтов и выбирает нужный сам, по заголовку Host, поэтому здесь один блок на # все имена, а не блок на сайт. Имена рендерятся из goatcounter_sites # (group_vars/all/main.yml) — того же списка, по которому плейбук goatcounter # заводит сами сайты, чтобы конфиг прокси и база не разъезжались. # # Без forward_auth: эндпоинты /count и /count.js обязаны быть публичными, их # дёргает трекер с сайта. Дашборд закрыт собственным логином goatcounter. {{ goatcounter_sites | join(', ') }} { tls anwinged@ya.ru import common reverse_proxy { to goatcounter_app:8080 } } goaccess.vakhrushev.me { tls anwinged@ya.ru import common forward_auth authelia_app:9091 { uri /api/authz/forward-auth copy_headers Remote-User Remote-Groups Remote-Email Remote-Name } @websocket { header Connection *Upgrade* header Upgrade websocket } reverse_proxy @websocket goaccess_processor:7890 reverse_proxy goaccess_app:8080 } # Bifrost — внутренний LLM-шлюз. Веб-UI (дашборд + LLM-логи + ключи) закрыт за # Authelia (2FA). Сам API tududi дёргает не через Caddy, а по web_proxy_network. bifrost.vakhrushev.me { tls anwinged@ya.ru import common forward_auth authelia_app:9091 { uri /api/authz/forward-auth copy_headers Remote-User Remote-Groups Remote-Email Remote-Name } reverse_proxy bifrost_app:8080 }