feat: add wintermute host as dedicated reverse proxy

Minimal LXC host importing only core.nix — no build toolchains, no
Home Manager. Caddy config migrated from alt with all existing vhosts
intact. Ready to clone from bootstrap template and deploy.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
Alexander Wainwright 2026-04-11 10:55:46 +10:00
parent 28e7103375
commit 4c5a639720
3 changed files with 103 additions and 0 deletions

View file

@ -89,6 +89,14 @@
(mkHomeManagerConfig {})
];
};
wintermute = nixpkgs.lib.nixosSystem {
system = "x86_64-linux";
specialArgs = { inherit inputs; };
modules = [
./hosts/wintermute/configuration.nix
];
};
bootstrap = nixpkgs.lib.nixosSystem {
system = "x86_64-linux";
specialArgs = { inherit inputs; };

View file

@ -0,0 +1,60 @@
{ config, pkgs, inputs, lib, ... }:
let
# String = simple site, Attrset = custom site.
sites = {
"analytics.figtree.dev" = "http://192.168.80.1:3300";
"figtree.dev" = "http://192.168.1.63:8080";
"files.figtree.dev" = "http://192.168.80.4:8080";
"git.figtree.dev" = "http://192.168.80.8:3000";
"nc.figtree.dev" = "http://192.168.1.62:11000";
"paperless.figtree.dev" = "http://192.168.1.63:8010";
"photos.figtree.dev" = "http://192.168.80.1:2283";
"shiori.figtree.dev" = "http://192.168.80.4:8234";
"tasks.figtree.dev" = "http://192.168.80.7:3456";
"www.figtree.dev" = "http://192.168.1.63:8080";
"ha.figtree.dev" = "http://192.168.1.50:8123";
# "budget.figtree.dev" = "http://192.168.80.1:5006";
# .lan domains automatically get "tls internal"
"home.lan" = "http://192.168.1.63:3000";
"budget.lan" = "http://192.168.80.1:5006";
"torrent.lan" = "http://192.168.1.65:8080";
"books.lan" = "http://192.168.80.4:8010";
"recipes.lan" = "http://192.168.80.4:8222";
"jelly.lan" = "http://192.168.80.4:8096";
"plex.lan" = "http://192.168.1.63:32400";
};
# Normalize sites:
# 1. Turn strings into { backend = "..."; }.
# 2. Automatically prepend `tls internal` for any domain ending in .lan.
normalizedSites = lib.mapAttrs (domain: siteConfig:
let
baseConfig = if lib.isString siteConfig then { backend = siteConfig; } else siteConfig;
isLanDomain = lib.hasSuffix ".lan" domain;
in
if isLanDomain then
baseConfig // {
extraBefore = ''
tls internal
${lib.optionalString (baseConfig ? extraBefore) baseConfig.extraBefore}
'';
}
else
baseConfig
) sites;
mkVHost = cfg: {
extraConfig = ''
${lib.optionalString (cfg ? extraBefore) cfg.extraBefore}
reverse_proxy ${cfg.backend}
${lib.optionalString (cfg ? extra) cfg.extra}
'';
};
in
{
services.caddy = {
enable = true;
virtualHosts = lib.mapAttrs (_: cfg: mkVHost cfg) normalizedSites;
};
}

View file

@ -0,0 +1,35 @@
{ config, modulesPath, pkgs, inputs, ... }:
{
imports = [
(modulesPath + "/virtualisation/proxmox-lxc.nix")
../modules/core.nix
./caddy.nix
];
nix.settings.sandbox = false;
proxmoxLXC = {
manageNetwork = false;
privileged = true;
};
networking.hostName = "wintermute";
networking.firewall.allowedTCPPorts = [ 80 443 ];
services.avahi = {
enable = true;
nssmdns4 = true;
nssmdns6 = true;
publish = {
enable = true;
addresses = true;
};
openFirewall = true;
};
documentation.man.man-db.enable = false;
system.stateVersion = "25.11";
}