137 lines
5 KiB
Nix
137 lines
5 KiB
Nix
# heather — Caddy как единый edge (TLS termination, reverse proxy).
|
||
#
|
||
# Заменяет Traefik (k3s built-in, отключён) и старые Caddy на iscg-dev/jul11.
|
||
# Паттерн как на iscg-dev: system Caddy, конфиг декларативно в nix.
|
||
#
|
||
# Caddy терминирует TLS на :80/:443 и роутит по Host на:
|
||
# - host-сервисы (syncthing GUI на localhost:8384) — напрямую
|
||
# - docker-контейнеры (forgejo на localhost:3030 и т.д.) — проброшенные порты
|
||
#
|
||
# ACME: пока staging (чтобы не забанили Let's Encrypt пока DNS не переведён на
|
||
# heather). Когда A-записи iscg.dev → 51.250.45.111 — переключим на production
|
||
# (убрать acme_ca, Caddy использует production LE по умолчанию).
|
||
|
||
{ config, pkgs, lib, ... }:
|
||
|
||
let
|
||
# caddy/basic-auth под паролем. hash сгенерить:
|
||
# caddy hash-password --plaintext '<password>'
|
||
# (на heather: nix-shell -p caddy --run 'caddy hash-password ...')
|
||
# Защищает syncthing GUI снаружи (GUI слушает только 127.0.0.1:8384,
|
||
# Caddy проксирует sync.iscg.dev + basicauth).
|
||
# pi-web basicauth. Пароль в pass iscg.dev/pi-web/auth (plaintext).
|
||
# Hash сгенерить на heather: nix-shell -p caddy --run 'caddy hash-password --plaintext ...'
|
||
piBasicAuth = ''
|
||
basicauth {
|
||
mikl $2a$14$yqYiMGLvtPs0sLRZhu1/VOfiRO.CARIBcGGrFpo4iwOd9s4o4IVCy
|
||
}
|
||
'';
|
||
|
||
syncBasicAuth = ''
|
||
basicauth {
|
||
mikl $2a$14$ozHN9/aa4VhPX43NN8MKdODKvOoJ5MBpOUFhzkxwvb58ZI5b6eqEK
|
||
}
|
||
'';
|
||
|
||
in {
|
||
services.caddy = {
|
||
enable = true;
|
||
# DNS переведён на heather (2026-07-12). Production ACME.
|
||
# Если нужен staging обратно: раскомментировать acmeCA ниже.
|
||
# acmeCA = "https://acme-staging-v02.api.letsencrypt.org/directory";
|
||
email = "mikl@iscg.dev";
|
||
|
||
virtualHosts = {
|
||
# --- Syncthing GUI (host-сервис) ---
|
||
# header_up Host 127.0.0.1:8384 — обходим syncthing host-check (DNS
|
||
# rebinding protection): syncthing сравнивает Host header с адресом
|
||
# прослушивания (127.0.0.1:8384) и отдаёт 403 "Host check error" для
|
||
# внешних доменов. Подменяем Host на бэкенде.
|
||
"sync.iscg.dev".extraConfig = syncBasicAuth + ''
|
||
reverse_proxy 127.0.0.1:8384 {
|
||
header_up Host 127.0.0.1:8384
|
||
}
|
||
'';
|
||
|
||
# --- Контейнеры (arion, см. arion-compose.nix) ---
|
||
# Forgejo
|
||
"git.iscg.dev".extraConfig = ''
|
||
handle /robots.txt {
|
||
header Content-Type text/plain
|
||
respond "User-agent: *
|
||
Allow: /" 200
|
||
}
|
||
reverse_proxy 127.0.0.1:3030
|
||
'';
|
||
|
||
# Matrix tuwunel (homeserver)
|
||
"iscg.dev".extraConfig = ''
|
||
# Static file sharing (https://iscg.dev/files/<name>).
|
||
# handle_path stripает /files/ prefix → file_server ищет в root.
|
||
# Не конфликтует с matrix (использует /_matrix/*, /.well-known/matrix).
|
||
handle_path /files/* {
|
||
root * /var/www/files
|
||
file_server
|
||
}
|
||
reverse_proxy 127.0.0.1:8008
|
||
encode zstd gzip
|
||
'';
|
||
|
||
# Matrix federation
|
||
"iscg.dev:8448".extraConfig = ''
|
||
reverse_proxy 127.0.0.1:8008
|
||
'';
|
||
|
||
# tuwunel-admin
|
||
"admin.iscg.dev".extraConfig = ''
|
||
reverse_proxy 127.0.0.1:8009
|
||
'';
|
||
|
||
# Cinny (matrix web client)
|
||
"chat.iscg.dev".extraConfig = ''
|
||
reverse_proxy 127.0.0.1:8080
|
||
encode zstd gzip
|
||
'';
|
||
|
||
# Jitsi Meet (Caddy v2 auto-handles WebSocket upgrade)
|
||
# Docs: https://jitsi.github.io/handbook/docs/devops-guide/devops-guide-docker#running-behind-a-reverse-proxy
|
||
"jitsi.iscg.dev".extraConfig = ''
|
||
reverse_proxy 127.0.0.1:8000
|
||
'';
|
||
|
||
# Teable
|
||
"teable.iscg.dev".extraConfig = ''
|
||
reverse_proxy 127.0.0.1:2345
|
||
'';
|
||
|
||
# Kaneo
|
||
"kaneo.iscg.dev".extraConfig = ''
|
||
reverse_proxy 127.0.0.1:3003
|
||
'';
|
||
|
||
# Silverbullet
|
||
"note.iscg.dev".extraConfig = ''
|
||
reverse_proxy 127.0.0.1:3001
|
||
'';
|
||
|
||
# Homepage (dashboard со всеми сервисами heather)
|
||
"home.iscg.dev".extraConfig = ''
|
||
reverse_proxy 127.0.0.1:3002
|
||
'';
|
||
|
||
# pi-web (web UI для pi coding agent)
|
||
# basicauth защищает весь vhost включая SSE /api/agent — leak нет.
|
||
"pi.iscg.dev".extraConfig = piBasicAuth + ''
|
||
reverse_proxy 127.0.0.1:30141
|
||
'';
|
||
|
||
# File explorer (directory listing) для раздачи файлов через браузер.
|
||
# browse включает Caddy's built-in directory listing. Корень /var/www/pub.
|
||
# Без auth — класть только публичные файлы.
|
||
"files.iscg.dev".extraConfig = ''
|
||
root * /var/www/pub
|
||
file_server browse
|
||
'';
|
||
};
|
||
};
|
||
}
|