Compare commits
No commits in common. "f62a61275841aa8aea1d755087327f5c0761da9e" and "34085e0870115da9e79c399f743d9fdf1aa07a5f" have entirely different histories.
f62a612758
...
34085e0870
16 changed files with 235 additions and 549 deletions
|
@ -17,7 +17,6 @@ in
|
||||||
|
|
||||||
(map lib.custom.relativeToRoot [
|
(map lib.custom.relativeToRoot [
|
||||||
"modules/global"
|
"modules/global"
|
||||||
"modules/nixos"
|
|
||||||
])
|
])
|
||||||
];
|
];
|
||||||
|
|
||||||
|
|
20
hosts/x86/cloud/config/caddy.nix
Normal file
20
hosts/x86/cloud/config/caddy.nix
Normal file
|
@ -0,0 +1,20 @@
|
||||||
|
{
|
||||||
|
services.caddy = {
|
||||||
|
enable = true;
|
||||||
|
virtualHosts = {
|
||||||
|
## Filerun ##
|
||||||
|
"drive.ryot.foo" = {
|
||||||
|
useACMEHost = "ryot.foo";
|
||||||
|
extraConfig = ''
|
||||||
|
reverse_proxy http://localhost:8181 {
|
||||||
|
header_up Host {host}
|
||||||
|
# header_up X-Forwarded-For {remote}
|
||||||
|
# header_up X-Forwarded-Proto {scheme}
|
||||||
|
# header_up X-Forwarded-Protocol {scheme}
|
||||||
|
# header_up X-Forwarded-Port {server_port}
|
||||||
|
}
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
|
@ -1,7 +0,0 @@
|
||||||
{
|
|
||||||
services.newt = {
|
|
||||||
enable = true;
|
|
||||||
id = "v0d4o5oras85zq8";
|
|
||||||
secret = "zyqht58kymdv4iij6t4no4ldnr7djg7wbfec95olnsg8jzf2";
|
|
||||||
};
|
|
||||||
}
|
|
|
@ -31,6 +31,7 @@ in
|
||||||
"hosts/global/core"
|
"hosts/global/core"
|
||||||
|
|
||||||
## Optional Configs ##
|
## Optional Configs ##
|
||||||
|
"hosts/global/common/acme"
|
||||||
"hosts/global/common/docker.nix"
|
"hosts/global/common/docker.nix"
|
||||||
])
|
])
|
||||||
];
|
];
|
||||||
|
|
119
hosts/x86/komo/config/caddy.nix
Normal file
119
hosts/x86/komo/config/caddy.nix
Normal file
|
@ -0,0 +1,119 @@
|
||||||
|
{
|
||||||
|
services.caddy = {
|
||||||
|
enable = true;
|
||||||
|
virtualHosts = {
|
||||||
|
|
||||||
|
## TOPH.CC ##
|
||||||
|
|
||||||
|
"blog.toph.cc" = {
|
||||||
|
useACMEHost = "toph.cc";
|
||||||
|
extraConfig = ''
|
||||||
|
reverse_proxy localhost:2368
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
## RYOT.FOO ##
|
||||||
|
|
||||||
|
"auth.ryot.foo" = {
|
||||||
|
useACMEHost = "ryot.foo";
|
||||||
|
extraConfig = ''
|
||||||
|
reverse_proxy localhost:9000 {
|
||||||
|
header_up Host {host}
|
||||||
|
header_up X-Forwarded-For {remote}
|
||||||
|
header_up X-Forwarded-Proto {scheme}
|
||||||
|
header_up X-Forwarded-Protocol {scheme}
|
||||||
|
header_up X-Forwarded-Port {server_port}
|
||||||
|
}
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
"frp.ryot.foo" = {
|
||||||
|
useACMEHost = "ryot.foo";
|
||||||
|
extraConfig = ''
|
||||||
|
route {
|
||||||
|
# 1) Proxy all outpost requests back to Authentik
|
||||||
|
reverse_proxy /outpost.goauthentik.io/* localhost:9000
|
||||||
|
|
||||||
|
# 2) Protect everything else via forward_auth
|
||||||
|
forward_auth localhost:9000 {
|
||||||
|
uri /outpost.goauthentik.io/auth/caddy
|
||||||
|
# copy user info headers from Authentik
|
||||||
|
copy_headers X-Authentik-Username X-Authentik-Groups \
|
||||||
|
X-Authentik-Entitlements X-Authentik-Email \
|
||||||
|
X-Authentik-Name X-Authentik-Uid \
|
||||||
|
X-Authentik-Jwt X-Authentik-Meta-Jwks \
|
||||||
|
X-Authentik-Meta-Outpost X-Authentik-Meta-Provider \
|
||||||
|
X-Authentik-Meta-App X-Authentik-Meta-Version
|
||||||
|
trusted_proxies private_ranges
|
||||||
|
}
|
||||||
|
|
||||||
|
# 3) If authenticated, proxy to your FRP UI
|
||||||
|
reverse_proxy localhost:4041 {
|
||||||
|
header_up Host {host}
|
||||||
|
header_up X-Real-IP {remote}
|
||||||
|
header_up X-Forwarded-For {remote}
|
||||||
|
header_up X-Forwarded-Proto {scheme}
|
||||||
|
header_up X-Forwarded-Port {server_port}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
"grafana.ryot.foo" = {
|
||||||
|
useACMEHost = "ryot.foo";
|
||||||
|
extraConfig = ''
|
||||||
|
reverse_proxy localhost:3001
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
"git.ryot.foo" = {
|
||||||
|
useACMEHost = "ryot.foo";
|
||||||
|
extraConfig = ''
|
||||||
|
reverse_proxy localhost:3003
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
"influx.ryot.foo" = {
|
||||||
|
useACMEHost = "ryot.foo";
|
||||||
|
extraConfig = ''
|
||||||
|
reverse_proxy localhost:8086
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
"home.ryot.foo" = {
|
||||||
|
useACMEHost = "ryot.foo";
|
||||||
|
extraConfig = ''
|
||||||
|
reverse_proxy localhost:7475
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
"komodo.ryot.foo" = {
|
||||||
|
useACMEHost = "ryot.foo";
|
||||||
|
extraConfig = ''
|
||||||
|
reverse_proxy localhost:9120
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
"map.ryot.foo" = {
|
||||||
|
useACMEHost = "ryot.foo";
|
||||||
|
extraConfig = ''
|
||||||
|
reverse_proxy localhost:25566
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
"outline.ryot.foo" = {
|
||||||
|
useACMEHost = "ryot.foo";
|
||||||
|
extraConfig = ''
|
||||||
|
reverse_proxy localhost:3480
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
"plane.ryot.foo" = {
|
||||||
|
useACMEHost = "ryot.foo";
|
||||||
|
extraConfig = ''
|
||||||
|
reverse_proxy localhost:3000
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
|
@ -1,8 +0,0 @@
|
||||||
{
|
|
||||||
services.newt = {
|
|
||||||
enable = true;
|
|
||||||
id = "7o2m62kaxpoi5pb";
|
|
||||||
secret = "t97xvz0itdkga6jr8x88oddxijzs73yslpsunlvyqu9xiyys";
|
|
||||||
useHostNetwork = true;
|
|
||||||
};
|
|
||||||
}
|
|
|
@ -5,7 +5,7 @@
|
||||||
*/
|
*/
|
||||||
{
|
{
|
||||||
# Containers
|
# Containers
|
||||||
virtualisation.oci-containers.containers."adguard" = {
|
virtualisation.oci-containers.containers."adguard-adguard" = {
|
||||||
image = "adguard/adguardhome:latest";
|
image = "adguard/adguardhome:latest";
|
||||||
volumes = [
|
volumes = [
|
||||||
"/etc/adguard/confdir:/opt/adguardhome/conf:rw"
|
"/etc/adguard/confdir:/opt/adguardhome/conf:rw"
|
||||||
|
@ -24,8 +24,7 @@
|
||||||
"--network=adguard_default"
|
"--network=adguard_default"
|
||||||
];
|
];
|
||||||
};
|
};
|
||||||
|
systemd.services."docker-adguard-adguard" = {
|
||||||
systemd.services."docker-adguard" = {
|
|
||||||
serviceConfig = {
|
serviceConfig = {
|
||||||
Restart = lib.mkOverride 90 "always";
|
Restart = lib.mkOverride 90 "always";
|
||||||
RestartMaxDelaySec = lib.mkOverride 90 "1m";
|
RestartMaxDelaySec = lib.mkOverride 90 "1m";
|
||||||
|
|
72
hosts/x86/proxy/config/caddy.nix
Normal file
72
hosts/x86/proxy/config/caddy.nix
Normal file
|
@ -0,0 +1,72 @@
|
||||||
|
{
|
||||||
|
services.caddy = {
|
||||||
|
enable = true;
|
||||||
|
virtualHosts = {
|
||||||
|
"adguard.ryot.foo" = {
|
||||||
|
useACMEHost = "ryot.foo";
|
||||||
|
extraConfig = ''
|
||||||
|
reverse_proxy localhost:3000
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
"cloudflared.ryot.foo" = {
|
||||||
|
useACMEHost = "ryot.foo";
|
||||||
|
extraConfig = ''
|
||||||
|
reverse_proxy localhost:14333
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
## openWRT ##
|
||||||
|
|
||||||
|
"wrt.ryot.foo" = {
|
||||||
|
useACMEHost = "ryot.foo";
|
||||||
|
extraConfig = ''
|
||||||
|
reverse_proxy http://104.40.3.1 {
|
||||||
|
header_up Host {host}
|
||||||
|
header_up X-Real-IP {remote}
|
||||||
|
header_up X-Forwarded-For {remote}
|
||||||
|
header_up X-Forwarded-Proto {scheme}
|
||||||
|
header_up X-Forwarded-Port {server_port}
|
||||||
|
}
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
## PROXMOX NODES ##
|
||||||
|
|
||||||
|
"ochre.ryot.foo" = {
|
||||||
|
useACMEHost = "ryot.foo";
|
||||||
|
extraConfig = ''
|
||||||
|
reverse_proxy https://104.40.3.2:8006 {
|
||||||
|
transport http {
|
||||||
|
tls_insecure_skip_verify
|
||||||
|
# optional: tls_server_name 104.40.3.2
|
||||||
|
}
|
||||||
|
# ensure Proxmox sees the right Host
|
||||||
|
header_up Host {host}
|
||||||
|
header_up X-Real-IP {remote}
|
||||||
|
header_up X-Forwarded-For {remote}
|
||||||
|
header_up X-Forwarded-Proto {scheme}
|
||||||
|
header_up X-Forwarded-Port {server_port}
|
||||||
|
}
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
"pve.ryot.foo" = {
|
||||||
|
useACMEHost = "ryot.foo";
|
||||||
|
extraConfig = ''
|
||||||
|
reverse_proxy https://104.40.3.3:8006 {
|
||||||
|
transport http {
|
||||||
|
tls_insecure_skip_verify
|
||||||
|
# optional: tls_server_name 104.40.3.3
|
||||||
|
}
|
||||||
|
header_up Host {host}
|
||||||
|
header_up X-Real-IP {remote}
|
||||||
|
header_up X-Forwarded-For {remote}
|
||||||
|
header_up X-Forwarded-Proto {scheme}
|
||||||
|
header_up X-Forwarded-Port {server_port}
|
||||||
|
}
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
|
@ -1,8 +0,0 @@
|
||||||
{
|
|
||||||
services.newt = {
|
|
||||||
enable = true;
|
|
||||||
id = "1jh3j2bhucdiq09";
|
|
||||||
secret = "f51n59bjwbg9c1wuyjg62my634mqqs1y199cwd1bxq3bes6p";
|
|
||||||
useHostNetwork = true;
|
|
||||||
};
|
|
||||||
}
|
|
|
@ -1,156 +0,0 @@
|
||||||
# Auto-generated using compose2nix v0.3.1.
|
|
||||||
{
|
|
||||||
pkgs,
|
|
||||||
lib,
|
|
||||||
config,
|
|
||||||
...
|
|
||||||
}:
|
|
||||||
|
|
||||||
{
|
|
||||||
# Containers
|
|
||||||
virtualisation.oci-containers.containers."gerbil" = {
|
|
||||||
image = "fosrl/gerbil:1.0.0";
|
|
||||||
volumes = [
|
|
||||||
"/etc/pangolin/config:/var/config:rw"
|
|
||||||
];
|
|
||||||
ports = [
|
|
||||||
"51820:51820/udp"
|
|
||||||
"443:443/tcp"
|
|
||||||
"222:222/tcp"
|
|
||||||
"80:80/tcp"
|
|
||||||
];
|
|
||||||
cmd = [
|
|
||||||
"--reachableAt=http://gerbil:3003"
|
|
||||||
"--generateAndSaveKeyTo=/var/config/key"
|
|
||||||
"--remoteConfig=http://pangolin:3001/api/v1/gerbil/get-config"
|
|
||||||
"--reportBandwidthTo=http://pangolin:3001/api/v1/gerbil/receive-bandwidth"
|
|
||||||
];
|
|
||||||
dependsOn = [
|
|
||||||
"pangolin"
|
|
||||||
];
|
|
||||||
log-driver = "journald";
|
|
||||||
extraOptions = [
|
|
||||||
"--cap-add=NET_ADMIN"
|
|
||||||
# "--cap-add=SYS_MODULE"
|
|
||||||
"--network-alias=gerbil"
|
|
||||||
"--network=pangolin"
|
|
||||||
];
|
|
||||||
};
|
|
||||||
systemd.services."docker-gerbil" = {
|
|
||||||
serviceConfig = {
|
|
||||||
Restart = lib.mkOverride 90 "always";
|
|
||||||
RestartMaxDelaySec = lib.mkOverride 90 "1m";
|
|
||||||
RestartSec = lib.mkOverride 90 "100ms";
|
|
||||||
RestartSteps = lib.mkOverride 90 9;
|
|
||||||
};
|
|
||||||
after = [
|
|
||||||
"docker-network-pangolin.service"
|
|
||||||
];
|
|
||||||
requires = [
|
|
||||||
"docker-network-pangolin.service"
|
|
||||||
];
|
|
||||||
partOf = [
|
|
||||||
"docker-compose-pangolin-root.target"
|
|
||||||
];
|
|
||||||
wantedBy = [
|
|
||||||
"docker-compose-pangolin-root.target"
|
|
||||||
];
|
|
||||||
};
|
|
||||||
virtualisation.oci-containers.containers."pangolin" = {
|
|
||||||
image = "fosrl/pangolin:1.5.1";
|
|
||||||
volumes = [
|
|
||||||
"/etc/pangolin/config:/app/config:rw"
|
|
||||||
];
|
|
||||||
log-driver = "journald";
|
|
||||||
extraOptions = [
|
|
||||||
"--health-cmd=[\"curl\", \"-f\", \"http://localhost:3001/api/v1/\"]"
|
|
||||||
"--health-interval=3s"
|
|
||||||
"--health-retries=15"
|
|
||||||
"--health-timeout=3s"
|
|
||||||
"--network-alias=pangolin"
|
|
||||||
"--network=pangolin"
|
|
||||||
];
|
|
||||||
};
|
|
||||||
|
|
||||||
systemd.services."docker-pangolin" = {
|
|
||||||
serviceConfig = {
|
|
||||||
Restart = lib.mkOverride 90 "always";
|
|
||||||
RestartMaxDelaySec = lib.mkOverride 90 "1m";
|
|
||||||
RestartSec = lib.mkOverride 90 "100ms";
|
|
||||||
RestartSteps = lib.mkOverride 90 9;
|
|
||||||
};
|
|
||||||
after = [
|
|
||||||
"docker-network-pangolin.service"
|
|
||||||
"pangolin-config-sync.service"
|
|
||||||
];
|
|
||||||
requires = [
|
|
||||||
"docker-network-pangolin.service"
|
|
||||||
"pangolin-config-sync.service"
|
|
||||||
];
|
|
||||||
partOf = [
|
|
||||||
"docker-compose-pangolin-root.target"
|
|
||||||
];
|
|
||||||
wantedBy = [
|
|
||||||
"docker-compose-pangolin-root.target"
|
|
||||||
];
|
|
||||||
};
|
|
||||||
|
|
||||||
virtualisation.oci-containers.containers."traefik" = {
|
|
||||||
image = "traefik:v3.4.0";
|
|
||||||
environment = {
|
|
||||||
"CLOUDFLARE_DNS_API_TOKEN" = config.secretsSpec.api.cloudflare;
|
|
||||||
};
|
|
||||||
volumes = [
|
|
||||||
"/etc/pangolin/config/letsencrypt:/letsencrypt:rw"
|
|
||||||
"/etc/pangolin/config/traefik:/etc/traefik:ro"
|
|
||||||
];
|
|
||||||
cmd = [ "--configFile=/etc/traefik/traefik_config.yml" ];
|
|
||||||
dependsOn = [
|
|
||||||
"gerbil"
|
|
||||||
"pangolin"
|
|
||||||
];
|
|
||||||
log-driver = "journald";
|
|
||||||
extraOptions = [
|
|
||||||
"--network=container:gerbil"
|
|
||||||
];
|
|
||||||
};
|
|
||||||
systemd.services."docker-traefik" = {
|
|
||||||
serviceConfig = {
|
|
||||||
Restart = lib.mkOverride 90 "always";
|
|
||||||
RestartMaxDelaySec = lib.mkOverride 90 "1m";
|
|
||||||
RestartSec = lib.mkOverride 90 "100ms";
|
|
||||||
RestartSteps = lib.mkOverride 90 9;
|
|
||||||
};
|
|
||||||
partOf = [
|
|
||||||
"docker-compose-pangolin-root.target"
|
|
||||||
];
|
|
||||||
wantedBy = [
|
|
||||||
"docker-compose-pangolin-root.target"
|
|
||||||
];
|
|
||||||
};
|
|
||||||
|
|
||||||
# Networks
|
|
||||||
systemd.services."docker-network-pangolin" = {
|
|
||||||
path = [ pkgs.docker ];
|
|
||||||
serviceConfig = {
|
|
||||||
Type = "oneshot";
|
|
||||||
RemainAfterExit = true;
|
|
||||||
ExecStop = "docker network rm -f pangolin";
|
|
||||||
};
|
|
||||||
script = ''
|
|
||||||
docker network inspect pangolin || docker network create pangolin --driver=bridge
|
|
||||||
'';
|
|
||||||
partOf = [ "docker-compose-pangolin-root.target" ];
|
|
||||||
wantedBy = [ "docker-compose-pangolin-root.target" ];
|
|
||||||
};
|
|
||||||
|
|
||||||
# Root service
|
|
||||||
# When started, this will automatically create all resources and start
|
|
||||||
# the containers. When stopped, this will teardown all resources.
|
|
||||||
systemd.targets."docker-compose-pangolin-root" = {
|
|
||||||
unitConfig = {
|
|
||||||
Description = "Root target generated by compose2nix.";
|
|
||||||
};
|
|
||||||
wantedBy = [ "multi-user.target" ];
|
|
||||||
};
|
|
||||||
}
|
|
|
@ -1,230 +0,0 @@
|
||||||
{
|
|
||||||
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
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
}
|
|
20
hosts/x86/sock/config/caddy.nix
Normal file
20
hosts/x86/sock/config/caddy.nix
Normal file
|
@ -0,0 +1,20 @@
|
||||||
|
{
|
||||||
|
services.caddy = {
|
||||||
|
enable = true;
|
||||||
|
virtualHosts = {
|
||||||
|
"upsnap.ryot.foo" = {
|
||||||
|
useACMEHost = "ryot.foo";
|
||||||
|
extraConfig = ''
|
||||||
|
reverse_proxy localhost:8090
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
"sock.ryot.foo" = {
|
||||||
|
useACMEHost = "ryot.foo";
|
||||||
|
extraConfig = ''
|
||||||
|
reverse_proxy localhost:9120
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
|
@ -1,7 +0,0 @@
|
||||||
{
|
|
||||||
services.newt = {
|
|
||||||
enable = true;
|
|
||||||
id = "3p15lzqz0ep9f46";
|
|
||||||
secret = "8uz056bzh22vuemtsxda31ibiu7jkqmyn1b7bifbqk38nlm4";
|
|
||||||
};
|
|
||||||
}
|
|
|
@ -31,6 +31,7 @@ in
|
||||||
"hosts/global/core"
|
"hosts/global/core"
|
||||||
|
|
||||||
## Optional Configs ##
|
## Optional Configs ##
|
||||||
|
"hosts/global/common/acme"
|
||||||
"hosts/global/common/docker.nix"
|
"hosts/global/common/docker.nix"
|
||||||
])
|
])
|
||||||
];
|
];
|
||||||
|
|
|
@ -1,129 +0,0 @@
|
||||||
{
|
|
||||||
config,
|
|
||||||
lib,
|
|
||||||
pkgs,
|
|
||||||
...
|
|
||||||
}:
|
|
||||||
|
|
||||||
with lib;
|
|
||||||
|
|
||||||
let
|
|
||||||
cfg = config.services.newt;
|
|
||||||
in
|
|
||||||
{
|
|
||||||
options.services.newt = {
|
|
||||||
enable = mkEnableOption "Newt container service";
|
|
||||||
|
|
||||||
id = mkOption {
|
|
||||||
type = types.str;
|
|
||||||
description = "Newt ID for authentication";
|
|
||||||
};
|
|
||||||
|
|
||||||
image = mkOption {
|
|
||||||
type = types.str;
|
|
||||||
default = "fosrl/newt";
|
|
||||||
description = "Docker image to use for Newt";
|
|
||||||
};
|
|
||||||
|
|
||||||
networkName = mkOption {
|
|
||||||
type = types.str;
|
|
||||||
default = "newt";
|
|
||||||
description = "Docker network name to use";
|
|
||||||
};
|
|
||||||
|
|
||||||
networkAlias = mkOption {
|
|
||||||
type = types.str;
|
|
||||||
default = "newt";
|
|
||||||
description = "Network alias for the container";
|
|
||||||
};
|
|
||||||
|
|
||||||
pangolinEndpoint = mkOption {
|
|
||||||
type = types.str;
|
|
||||||
default = "https://pangolin.ryot.foo";
|
|
||||||
description = "Pangolin endpoint URL";
|
|
||||||
};
|
|
||||||
|
|
||||||
secret = mkOption {
|
|
||||||
type = types.str;
|
|
||||||
description = "Newt secret for authentication";
|
|
||||||
};
|
|
||||||
|
|
||||||
useHostNetwork = mkOption {
|
|
||||||
type = types.bool;
|
|
||||||
default = false;
|
|
||||||
description = "Whether to use host networking instead of Docker networks";
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
config = mkIf cfg.enable {
|
|
||||||
# Container
|
|
||||||
virtualisation.oci-containers.containers."newt" = {
|
|
||||||
image = cfg.image;
|
|
||||||
environment = {
|
|
||||||
"DOCKER_SOCKET" = "/var/run/docker.sock";
|
|
||||||
"NEWT_ID" = cfg.id;
|
|
||||||
"NEWT_SECRET" = cfg.secret;
|
|
||||||
"PANGOLIN_ENDPOINT" = cfg.pangolinEndpoint;
|
|
||||||
};
|
|
||||||
volumes = [
|
|
||||||
"/var/run/docker.sock:/var/run/docker.sock:rw"
|
|
||||||
];
|
|
||||||
log-driver = "journald";
|
|
||||||
extraOptions =
|
|
||||||
if cfg.useHostNetwork then
|
|
||||||
[
|
|
||||||
"--network=host"
|
|
||||||
]
|
|
||||||
else
|
|
||||||
[
|
|
||||||
"--network-alias=${cfg.networkAlias}"
|
|
||||||
"--network=${cfg.networkName}"
|
|
||||||
];
|
|
||||||
};
|
|
||||||
|
|
||||||
# Container service with proper dependencies
|
|
||||||
systemd.services."docker-newt" = {
|
|
||||||
serviceConfig = {
|
|
||||||
Restart = lib.mkOverride 90 "always";
|
|
||||||
RestartMaxDelaySec = lib.mkOverride 90 "1m";
|
|
||||||
RestartSec = lib.mkOverride 90 "100ms";
|
|
||||||
RestartSteps = lib.mkOverride 90 9;
|
|
||||||
};
|
|
||||||
after = mkIf (!cfg.useHostNetwork) [
|
|
||||||
"docker-network-${cfg.networkName}.service"
|
|
||||||
];
|
|
||||||
requires = mkIf (!cfg.useHostNetwork) [
|
|
||||||
"docker-network-${cfg.networkName}.service"
|
|
||||||
];
|
|
||||||
partOf = [
|
|
||||||
"docker-compose-newt-root.target"
|
|
||||||
];
|
|
||||||
wantedBy = [
|
|
||||||
"docker-compose-newt-root.target"
|
|
||||||
];
|
|
||||||
};
|
|
||||||
|
|
||||||
# Docker network service (only when not using host network)
|
|
||||||
systemd.services."docker-network-${cfg.networkName}" = mkIf (!cfg.useHostNetwork) {
|
|
||||||
path = [ pkgs.docker ];
|
|
||||||
serviceConfig = {
|
|
||||||
Type = "oneshot";
|
|
||||||
RemainAfterExit = true;
|
|
||||||
ExecStop = "docker network rm -f ${cfg.networkName}";
|
|
||||||
};
|
|
||||||
script = ''
|
|
||||||
docker network inspect ${cfg.networkName} || docker network create ${cfg.networkName}
|
|
||||||
'';
|
|
||||||
partOf = [ "docker-compose-newt-root.target" ];
|
|
||||||
wantedBy = [ "docker-compose-newt-root.target" ];
|
|
||||||
};
|
|
||||||
|
|
||||||
# Root target
|
|
||||||
systemd.targets."docker-compose-newt-root" = {
|
|
||||||
unitConfig = {
|
|
||||||
Description = "Root target generated by compose2nix.";
|
|
||||||
};
|
|
||||||
wantedBy = [ "multi-user.target" ];
|
|
||||||
};
|
|
||||||
};
|
|
||||||
}
|
|
BIN
secrets.nix
BIN
secrets.nix
Binary file not shown.
Loading…
Add table
Reference in a new issue