- 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
230 lines
5.7 KiB
Nix
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
|
|
'';
|
|
};
|
|
}
|