dot.nix/hosts/x86/proxy/config/pangolin/default.nix
Chris Toph 86495b11a7 Replace caddy with newt; add pangolin as a homelab Proxy service
- Add newt service definitions and corresponding nix modules
- Replace caddy configurations across cloud, komo, proxy, and sock hosts with newt
- Implement compose configurations for pangolin in proxy host
- Update adguard naming and systemd service definitions
- Refresh secrets with newt and pangolin credentials
2025-06-14 18:47:31 -04:00

230 lines
5.7 KiB
Nix

{
lib,
config,
pkgs,
...
}:
let
smtp = config.secretsSpec.users.admin.smtp;
pangolin = config.secretsSpec.docker.pangolin;
# Create the configuration files as derivations
pangolinConfigFile = pkgs.writeText "pangolin-config.yml" ''
app:
dashboard_url: "https://pangolin.ryot.foo"
log_level: "debug"
save_logs: true
domains:
domain1:
base_domain: "ryot.foo"
cert_resolver: "letsencrypt"
prefer_wildcard_cert: true
domain2:
base_domain: "toph.cc"
cert_resolver: "letsencrypt"
prefer_wildcard_cert: true
domain3:
base_domain: "goldenlemon.cc"
cert_resolver: "letsencrypt"
prefer_wildcard_cert: true
domain4:
base_domain: "kwahson.xyz"
cert_resolver: "letsencrypt"
prefer_wildcard_cert: true
server:
external_port: 3000
internal_port: 3001
next_port: 3002
internal_hostname: "pangolin"
session_cookie_name: "p_session_token"
resource_access_token_param: "p_token"
resource_access_token_headers:
id: "P-Access-Token-Id"
token: "P-Access-Token"
resource_session_request_param: "p_session_request"
secret: "${pangolin.SECRET}"
traefik:
cert_resolver: "letsencrypt"
http_entrypoint: "web"
https_entrypoint: "websecure"
gerbil:
start_port: 51820
base_endpoint: "pangolin.ryot.foo"
use_subdomain: false
block_size: 24
site_block_size: 30
subnet_group: 104.40.3.1/24
rate_limits:
global:
window_minutes: 1
max_requests: 100
email:
smtp_host: "${smtp.host}"
smtp_port: ${toString smtp.port}
smtp_user: "${smtp.user}"
smtp_pass: "${smtp.password}"
no_reply: "no-reply@ryot.foo"
users:
server_admin:
email: "${pangolin.USER}"
password: "${pangolin.PASSWORD}"
flags:
require_email_verification: true
disable_signup_without_invite: true
disable_user_create_org: true
allow_raw_resources: true
allow_base_domain_resources: true
'';
traefikConfigFile = pkgs.writeText "traefik-config.yml" ''
api:
insecure: true
dashboard: true
providers:
http:
endpoint: "http://pangolin:3001/api/v1/traefik-config"
pollInterval: "5s"
file:
filename: "/etc/traefik/dynamic_config.yml"
experimental:
plugins:
badger:
moduleName: "github.com/fosrl/badger"
version: "v1.2.0"
log:
level: "DEBUG"
format: "common"
certificatesResolvers:
letsencrypt:
acme:
dnsChallenge:
provider: cloudflare
delayBeforeCheck: 60
resolvers:
- "1.1.1.1:53"
- "8.8.8.8:53"
email: chris@toph.cc
storage: "/letsencrypt/acme.json"
caServer: "https://acme-v02.api.letsencrypt.org/directory"
entryPoints:
web:
address: ":80"
websecure:
address: ":443"
transport:
respondingTimeouts:
readTimeout: "30m"
http:
tls:
certResolver: "letsencrypt"
tcp-222:
address: ":222/tcp"
serversTransport:
insecureSkipVerify: true
'';
dynamicConfigFile = pkgs.writeText "dynamic-config.yml" ''
http:
middlewares:
redirect-to-https:
redirectScheme:
scheme: https
routers:
# HTTP to HTTPS redirect router
main-app-router-redirect:
rule: "Host(`pangolin.ryot.foo`)"
service: next-service
entryPoints:
- web
middlewares:
- redirect-to-https
# Next.js router
next-router:
rule: "Host(`pangolin.ryot.foo`) && !PathPrefix(`/api/v1`)"
service: next-service
entryPoints:
- websecure
tls:
certResolver: letsencrypt
domains:
- main: "ryot.foo"
sans:
- "*.ryot.foo"
# API router
api-router:
rule: "Host(`pangolin.ryot.foo`) && PathPrefix(`/api/v1`)"
service: api-service
entryPoints:
- websecure
tls:
certResolver: letsencrypt
# WebSocket router
ws-router:
rule: "Host(`pangolin.ryot.foo`)"
service: api-service
entryPoints:
- websecure
tls:
certResolver: letsencrypt
services:
next-service:
loadBalancer:
servers:
- url: "http://pangolin:3002"
api-service:
loadBalancer:
servers:
- url: "http://pangolin:3000"
'';
keyFile = pkgs.writeText "pangolin-key" pangolin.KEY;
in
{
imports = lib.custom.scanPaths ./.;
boot.kernelModules = [ "wireguard" ];
## Tmp files and Service to Avoid symlinks
systemd.tmpfiles.rules = [
"d /etc/pangolin/config 0755 root root -"
"d /etc/pangolin/config/traefik 0755 root root -"
"d /etc/pangolin/config/letsencrypt 0755 root root -"
];
systemd.services.pangolin-config-sync = {
description = "Sync Pangolin configuration files";
wantedBy = [ "multi-user.target" ];
before = [ "docker-compose-pangolin-root.target" ];
serviceConfig = {
Type = "oneshot";
RemainAfterExit = true;
};
script = ''
cp ${keyFile} /etc/pangolin/config/key
chmod 0600 /etc/pangolin/config/key
cp ${pangolinConfigFile} /etc/pangolin/config/config.yml
cp ${traefikConfigFile} /etc/pangolin/config/traefik/traefik_config.yml
cp ${dynamicConfigFile} /etc/pangolin/config/traefik/dynamic_config.yml
'';
};
}