Compare commits
3 commits
34085e0870
...
79e14c015c
Author | SHA1 | Date | |
---|---|---|---|
79e14c015c | |||
9f2b2a986c | |||
86495b11a7 |
24 changed files with 624 additions and 305 deletions
2
.vscode/settings.json
vendored
2
.vscode/settings.json
vendored
|
@ -3,7 +3,7 @@
|
|||
"editor.formatOnSaveMode": "file",
|
||||
"explorer.fileNesting.patterns": {
|
||||
".gitignore": ".gitattributes, .envrc, readme",
|
||||
"flake.nix": "flake.lock, shell.nix, secrets.nix"
|
||||
"flake.nix": "flake.lock, *.nix"
|
||||
},
|
||||
"files.exclude": {
|
||||
".git-crypt": true
|
||||
|
|
50
flake.lock
generated
50
flake.lock
generated
|
@ -402,11 +402,11 @@
|
|||
},
|
||||
"hardware": {
|
||||
"locked": {
|
||||
"lastModified": 1749195551,
|
||||
"narHash": "sha256-W5GKQHgunda/OP9sbKENBZhMBDNu2QahoIPwnsF6CeM=",
|
||||
"lastModified": 1749832440,
|
||||
"narHash": "sha256-lfxhuxAaHlYFGr8yOrAXZqdMt8PrFLzjVqH9v3lQaoY=",
|
||||
"owner": "nixos",
|
||||
"repo": "nixos-hardware",
|
||||
"rev": "4602f7e1d3f197b3cb540d5accf5669121629628",
|
||||
"rev": "db030f62a449568345372bd62ed8c5be4824fa49",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
|
@ -443,11 +443,11 @@
|
|||
]
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1749483884,
|
||||
"narHash": "sha256-HdyfdVx0NbgrVtLY4lXdX9X/YE3PZjGZFnSyoAy1GJc=",
|
||||
"lastModified": 1749935160,
|
||||
"narHash": "sha256-lTLR7AyrrIS/b4frHKb5pw/gcPM0GgoGCURqeiOX9k8=",
|
||||
"owner": "nix-community",
|
||||
"repo": "home-manager",
|
||||
"rev": "74d196c9943a67908d1883f61154e594d03863e5",
|
||||
"rev": "8fabeb9c142a303e02270c3a3a0d8e00af9d0dfe",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
|
@ -529,11 +529,11 @@
|
|||
]
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1749348095,
|
||||
"narHash": "sha256-4KaUocEPNoU6gpFE6WPLMvMK5tmvJyc0qf84Mp8Chlw=",
|
||||
"lastModified": 1749847109,
|
||||
"narHash": "sha256-9i/A5yrjyYT63YZ6wOxOFru/kzQPIKZVSVWS1Clerr4=",
|
||||
"owner": "fufexan",
|
||||
"repo": "nix-gaming",
|
||||
"rev": "4221d80488883c40003f0704af78699a583f0c9f",
|
||||
"rev": "9a9f441bb894ee929e93596f0dc0f23c3d9a7532",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
|
@ -598,27 +598,27 @@
|
|||
},
|
||||
"nixpkgs-stable": {
|
||||
"locked": {
|
||||
"lastModified": 1749173751,
|
||||
"narHash": "sha256-ENY3y3v6S9ZmLDDLI3LUT8MXmfXg/fSt2eA4GCnMVCE=",
|
||||
"lastModified": 1749727998,
|
||||
"narHash": "sha256-mHv/yeUbmL91/TvV95p+mBVahm9mdQMJoqaTVTALaFw=",
|
||||
"owner": "NixOS",
|
||||
"repo": "nixpkgs",
|
||||
"rev": "ed29f002b6d6e5e7e32590deb065c34a31dc3e91",
|
||||
"rev": "fd487183437963a59ba763c0cc4f27e3447dd6dd",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "NixOS",
|
||||
"ref": "nixos-24.11",
|
||||
"ref": "nixos-25.05",
|
||||
"repo": "nixpkgs",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"nixpkgs-unstable": {
|
||||
"locked": {
|
||||
"lastModified": 1749285348,
|
||||
"narHash": "sha256-frdhQvPbmDYaScPFiCnfdh3B/Vh81Uuoo0w5TkWmmjU=",
|
||||
"lastModified": 1749794982,
|
||||
"narHash": "sha256-Kh9K4taXbVuaLC0IL+9HcfvxsSUx8dPB5s5weJcc9pc=",
|
||||
"owner": "NixOS",
|
||||
"repo": "nixpkgs",
|
||||
"rev": "3e3afe5174c561dee0df6f2c2b2236990146329f",
|
||||
"rev": "ee930f9755f58096ac6e8ca94a1887e0534e2d81",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
|
@ -630,11 +630,11 @@
|
|||
},
|
||||
"nixpkgs_2": {
|
||||
"locked": {
|
||||
"lastModified": 1749285348,
|
||||
"narHash": "sha256-frdhQvPbmDYaScPFiCnfdh3B/Vh81Uuoo0w5TkWmmjU=",
|
||||
"lastModified": 1749794982,
|
||||
"narHash": "sha256-Kh9K4taXbVuaLC0IL+9HcfvxsSUx8dPB5s5weJcc9pc=",
|
||||
"owner": "NixOS",
|
||||
"repo": "nixpkgs",
|
||||
"rev": "3e3afe5174c561dee0df6f2c2b2236990146329f",
|
||||
"rev": "ee930f9755f58096ac6e8ca94a1887e0534e2d81",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
|
@ -884,11 +884,11 @@
|
|||
"tinted-zed": "tinted-zed"
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1749481862,
|
||||
"narHash": "sha256-CXZL1Kt4rP1SAQhT4wCM207pcjkTeZMza9iIVFKV71c=",
|
||||
"lastModified": 1749905587,
|
||||
"narHash": "sha256-sZpQM+InPCYwJQiTxs/PCCupwbYNaSCFi2Hvpl1/pOo=",
|
||||
"owner": "danth",
|
||||
"repo": "stylix",
|
||||
"rev": "d73d8f6a4834716496bf8930a492b115cc3d7d17",
|
||||
"rev": "77a8b26520f48305f3b1bacffaa8740dde8afa2a",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
|
@ -1172,11 +1172,11 @@
|
|||
]
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1748971473,
|
||||
"narHash": "sha256-0Xh6sZI86Ops6u7wyDQlVvV+MvRRXIDb1r3sMnLNk9M=",
|
||||
"lastModified": 1749874024,
|
||||
"narHash": "sha256-bFNesH4+qRcsA/bL+HT4ep1rNkn1A1AZ2RmlZlETwlw=",
|
||||
"owner": "youwen5",
|
||||
"repo": "zen-browser-flake",
|
||||
"rev": "5cc269976ca876674d8ccc7f40debb61e05583ab",
|
||||
"rev": "d3d3c12550f1d4196bd7f2971c65ffde2bd92a07",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
|
|
|
@ -321,20 +321,26 @@ with lib.hm.gvariant;
|
|||
vertical-margin-bottom = 8;
|
||||
window-gap = 8;
|
||||
winprops = [
|
||||
''
|
||||
{"wm_class":"Code","preferredWidth":"70%","spaceIndex":0}
|
||||
''
|
||||
''
|
||||
{"wm_class":"com.mitchellh.ghostty","scratch_layer":true}
|
||||
''
|
||||
''
|
||||
{"wm_class":"code","preferredWidth":"70%"}
|
||||
''
|
||||
''
|
||||
{"wm_class":"discord","preferredWidth":"100%","spaceIndex":1}
|
||||
''
|
||||
''
|
||||
{"wm_class":"gnome-control-center","scratch_layer":true}
|
||||
''
|
||||
''
|
||||
{"wm_class":"gnome-extensions-app","scratch_layer":true}
|
||||
''
|
||||
''
|
||||
{"wm_class":"org.gnome.Nautilus","scratch_layer":true}
|
||||
''
|
||||
''
|
||||
{"wm_class":"gnome-control-center","scratch_layer":true}
|
||||
{"wm_class":"TelegramDesktop","spaceIndex":1}
|
||||
''
|
||||
];
|
||||
};
|
||||
|
|
|
@ -111,10 +111,10 @@ with lib.hm.gvariant;
|
|||
"Microphone 8211 USB Live camera"
|
||||
];
|
||||
excluded-output-names = [
|
||||
"Analog Output – HyperX Cloud Alpha S"
|
||||
"Analog Output \8211 HyperX Cloud Alpha S"
|
||||
"Analog Output 8211 HyperX Cloud Alpha S"
|
||||
"Analog Output 8211 HyperX Cloud Alpha S"
|
||||
# "Analog Output – HyperX Cloud Alpha S"
|
||||
# "Analog Output \8211 HyperX Cloud Alpha S"
|
||||
# "Analog Output 8211 HyperX Cloud Alpha S"
|
||||
# "Analog Output 8211 HyperX Cloud Alpha S"
|
||||
"HDMI / DisplayPort – Rembrandt Radeon High Definition Audio Controller"
|
||||
"HDMI / DisplayPort \8211 Rembrandt Radeon High Definition Audio Controller"
|
||||
"HDMI / DisplayPort 8211 Rembrandt Radeon High Definition Audio Controller"
|
||||
|
@ -148,7 +148,7 @@ with lib.hm.gvariant;
|
|||
])
|
||||
(lib.hm.gvariant.mkDictionaryEntry [
|
||||
"Analog Output – HyperX Cloud Alpha S"
|
||||
"NO"
|
||||
"Cloud S - 7.1"
|
||||
])
|
||||
(lib.hm.gvariant.mkDictionaryEntry [
|
||||
"Digital Output (S/PDIF) – HyperX Cloud Alpha S"
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
###############################################################
|
||||
#
|
||||
# Caenus - Oracle VPS
|
||||
# NixOS VPS, ____, ____
|
||||
# NixOS VPS, 4vCPU, 24Ggb RAM, 200GB
|
||||
#
|
||||
# Public IP
|
||||
#
|
||||
|
|
3
hosts/arm/wsl/default.nix
Normal file
3
hosts/arm/wsl/default.nix
Normal file
|
@ -0,0 +1,3 @@
|
|||
{
|
||||
# TBD; Not working well yet in X Elite Laptop
|
||||
}
|
|
@ -1,11 +1,7 @@
|
|||
{ pkgs, config, ... }:
|
||||
{
|
||||
## DE ##
|
||||
|
||||
services.xserver = {
|
||||
enable = true;
|
||||
|
||||
desktopManager.gnome = {
|
||||
services.desktopManager.gnome = {
|
||||
enable = true;
|
||||
extraGSettingsOverridePackages = [ pkgs.mutter ];
|
||||
extraGSettingsOverrides = ''
|
||||
|
@ -13,7 +9,8 @@
|
|||
experimental-features=['scale-monitor-framebuffer']
|
||||
'';
|
||||
};
|
||||
displayManager = {
|
||||
|
||||
services.displayManager = {
|
||||
gdm = {
|
||||
enable = true;
|
||||
wayland = true;
|
||||
|
@ -24,12 +21,6 @@
|
|||
};
|
||||
};
|
||||
|
||||
xkb = {
|
||||
layout = "us";
|
||||
variant = "";
|
||||
};
|
||||
};
|
||||
|
||||
#INFO: Fix for autoLogin
|
||||
systemd.services."getty@tty1".enable = false;
|
||||
systemd.services."autovt@tty1".enable = false;
|
||||
|
@ -54,7 +45,6 @@
|
|||
];
|
||||
|
||||
## Exclusions ##
|
||||
services.xserver.excludePackages = [ pkgs.xterm ];
|
||||
environment.gnome.excludePackages = (
|
||||
with pkgs;
|
||||
[
|
||||
|
|
|
@ -17,6 +17,7 @@ in
|
|||
|
||||
(map lib.custom.relativeToRoot [
|
||||
"modules/global"
|
||||
"modules/nixos"
|
||||
])
|
||||
];
|
||||
|
||||
|
@ -104,9 +105,6 @@ in
|
|||
min-free = 128000000; # 128MB
|
||||
max-free = 1000000000; # 1GB
|
||||
|
||||
substituters = [ "https://hyprland.cachix.org" ];
|
||||
trusted-public-keys = [ "hyprland.cachix.org-1:a7pgxzMz7+chwVL3/pzj6jIBMioiJM7ypFP8PwtkuGc=" ];
|
||||
|
||||
trusted-users = [ "@wheel" ];
|
||||
# Deduplicate and optimize nix store
|
||||
auto-optimise-store = true;
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
{ lib, ... }:
|
||||
{
|
||||
programs.ssh.startAgent = true;
|
||||
|
||||
|
@ -7,8 +8,8 @@
|
|||
|
||||
settings = {
|
||||
AllowUsers = null; # everyone
|
||||
PasswordAuthentication = false;
|
||||
PermitRootLogin = "no";
|
||||
PasswordAuthentication = lib.mkDefault false;
|
||||
PermitRootLogin = lib.mkDefault "no";
|
||||
KbdInteractiveAuthentication = false;
|
||||
# Automatically remove stale sockets
|
||||
StreamLocalBindUnlink = "yes";
|
||||
|
|
|
@ -1,20 +0,0 @@
|
|||
{
|
||||
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}
|
||||
}
|
||||
'';
|
||||
};
|
||||
};
|
||||
};
|
||||
}
|
11
hosts/x86/cloud/config/newt.nix
Normal file
11
hosts/x86/cloud/config/newt.nix
Normal file
|
@ -0,0 +1,11 @@
|
|||
{ config, ... }:
|
||||
let
|
||||
cfg = config.secretsSpec.docker.newt-cloud;
|
||||
in
|
||||
{
|
||||
services.newt = {
|
||||
enable = true;
|
||||
id = cfg.ID;
|
||||
secret = cfg.SECRET;
|
||||
};
|
||||
}
|
|
@ -31,7 +31,6 @@ in
|
|||
"hosts/global/core"
|
||||
|
||||
## Optional Configs ##
|
||||
"hosts/global/common/acme"
|
||||
"hosts/global/common/docker.nix"
|
||||
])
|
||||
];
|
||||
|
|
|
@ -1,119 +0,0 @@
|
|||
{
|
||||
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
|
||||
'';
|
||||
};
|
||||
};
|
||||
};
|
||||
}
|
12
hosts/x86/komo/config/newt.nix
Normal file
12
hosts/x86/komo/config/newt.nix
Normal file
|
@ -0,0 +1,12 @@
|
|||
{ config, ... }:
|
||||
let
|
||||
cfg = config.secretsSpec.docker.newt-komo;
|
||||
in
|
||||
{
|
||||
services.newt = {
|
||||
enable = true;
|
||||
id = cfg.ID;
|
||||
secret = cfg.SECRET;
|
||||
useHostNetwork = true;
|
||||
};
|
||||
}
|
|
@ -5,7 +5,7 @@
|
|||
*/
|
||||
{
|
||||
# Containers
|
||||
virtualisation.oci-containers.containers."adguard-adguard" = {
|
||||
virtualisation.oci-containers.containers."adguard" = {
|
||||
image = "adguard/adguardhome:latest";
|
||||
volumes = [
|
||||
"/etc/adguard/confdir:/opt/adguardhome/conf:rw"
|
||||
|
@ -24,7 +24,8 @@
|
|||
"--network=adguard_default"
|
||||
];
|
||||
};
|
||||
systemd.services."docker-adguard-adguard" = {
|
||||
|
||||
systemd.services."docker-adguard" = {
|
||||
serviceConfig = {
|
||||
Restart = lib.mkOverride 90 "always";
|
||||
RestartMaxDelaySec = lib.mkOverride 90 "1m";
|
||||
|
|
|
@ -1,72 +0,0 @@
|
|||
{
|
||||
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}
|
||||
}
|
||||
'';
|
||||
};
|
||||
};
|
||||
};
|
||||
}
|
12
hosts/x86/proxy/config/newt.nix
Normal file
12
hosts/x86/proxy/config/newt.nix
Normal file
|
@ -0,0 +1,12 @@
|
|||
{ config, ... }:
|
||||
let
|
||||
cfg = config.secretsSpec.docker.newt-proxy;
|
||||
in
|
||||
{
|
||||
services.newt = {
|
||||
enable = true;
|
||||
id = cfg.ID;
|
||||
secret = cfg.SECRET;
|
||||
useHostNetwork = true;
|
||||
};
|
||||
}
|
156
hosts/x86/proxy/config/pangolin/compose.nix
Normal file
156
hosts/x86/proxy/config/pangolin/compose.nix
Normal file
|
@ -0,0 +1,156 @@
|
|||
# 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" ];
|
||||
};
|
||||
}
|
230
hosts/x86/proxy/config/pangolin/default.nix
Normal file
230
hosts/x86/proxy/config/pangolin/default.nix
Normal file
|
@ -0,0 +1,230 @@
|
|||
{
|
||||
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
|
||||
'';
|
||||
};
|
||||
}
|
|
@ -1,20 +0,0 @@
|
|||
{
|
||||
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
|
||||
'';
|
||||
};
|
||||
};
|
||||
};
|
||||
}
|
11
hosts/x86/sock/config/newt.nix
Normal file
11
hosts/x86/sock/config/newt.nix
Normal file
|
@ -0,0 +1,11 @@
|
|||
{ config, ... }:
|
||||
let
|
||||
cfg = config.secretsSpec.docker.newt-sock;
|
||||
in
|
||||
{
|
||||
services.newt = {
|
||||
enable = true;
|
||||
id = cfg.ID;
|
||||
secret = cfg.SECRET;
|
||||
};
|
||||
}
|
|
@ -16,7 +16,6 @@
|
|||
let
|
||||
username = "toph";
|
||||
user = config.secretsSpec.users.${username};
|
||||
firewall = config.secretsSpec.firewall.sock;
|
||||
in
|
||||
{
|
||||
imports = lib.flatten [
|
||||
|
@ -31,7 +30,6 @@ in
|
|||
"hosts/global/core"
|
||||
|
||||
## Optional Configs ##
|
||||
"hosts/global/common/acme"
|
||||
"hosts/global/common/docker.nix"
|
||||
])
|
||||
];
|
||||
|
@ -50,11 +48,6 @@ in
|
|||
|
||||
networking = {
|
||||
enableIPv6 = false;
|
||||
firewall = {
|
||||
allowedTCPPorts = firewall.allowedTCPPorts;
|
||||
allowedTCPPortRanges = firewall.allowedTCPPortRanges;
|
||||
allowedUDPPorts = firewall.allowedUDPPorts;
|
||||
};
|
||||
};
|
||||
|
||||
## System-wide packages ##
|
||||
|
|
127
modules/nixos/newt.nix
Normal file
127
modules/nixos/newt.nix
Normal file
|
@ -0,0 +1,127 @@
|
|||
{
|
||||
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 {
|
||||
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}"
|
||||
];
|
||||
};
|
||||
|
||||
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