feat: full nix-topology

This commit is contained in:
Leon Schwarzäugl 2025-06-16 00:21:41 +02:00
parent ed15ef02bb
commit c7132d2d85
Signed by: swarsel
GPG key ID: 26A54C31F2A4FD84
38 changed files with 2464 additions and 807 deletions

View file

@ -563,8 +563,7 @@ Nix on Android also demands an own flake output, which is provided here.
lib.swarselsystems.forEachSystem (pkgs: import inputs.nix-topology {
inherit pkgs;
modules = [
# Your own file to define global topology. Works in principle like a nixos module but uses different options.
# ./topology.nix
"${self}/topology"
{ inherit (self) nixosConfigurations; }
];
});
@ -836,6 +835,7 @@ My work machine. Built for more security, this is the gold standard of my config
swarselsystems = lib.recursiveUpdate
{
info = "Framework Laptop 16, 7940HS, RX7700S, 64GB RAM";
firewall = lib.mkForce true;
wallpaper = self + /wallpaper/lenovowp.png;
hasBluetooth = true;
@ -1093,6 +1093,7 @@ This is my main server that I run at home. It handles most tasks that require bi
swarselsystems = lib.recursiveUpdate
{
info = "ASRock J4105-ITX, 32GB RAM";
isImpermanence = false;
isSecureBoot = true;
isCrypted = true;
@ -1336,7 +1337,7 @@ This machine mainly acts as an external sync helper. It manages the following th
acmeRoot = null;
locations = {
"/" = {
proxyPass = "http://localhost:8384/";
proxyPass = "http://localhost:8384";
extraConfig = ''
client_max_body_size 0;
'';
@ -1428,6 +1429,7 @@ This machine mainly acts as an external sync helper. It manages the following th
swarselsystems = lib.recursiveUpdate
{
info = "VM.Standard.E2.1.Micro";
flakePath = "/root/.dotfiles";
isImpermanence = false;
isSecureBoot = false;
@ -1493,6 +1495,12 @@ This machine mainly acts as an external sync helper. It manages the following th
];
};
topology.self.interfaces.wg = {
addresses = ["192.168.3.4"];
renderer.hidePhysicalConnections = true;
virtual = true;
type = "wireguard";
};
networking = {
nftables.enable = lib.mkForce false;
@ -1534,26 +1542,13 @@ This machine mainly acts as an external sync helper. It manages the following th
services = {
nginx = {
virtualHosts = {
# "newway.swarsel.win" = {
# enableACME = true;
# forceSSL = true;
# acmeRoot = null;
# locations = {
# "/" = {
# proxyPass = "http://192.168.1.2:8080";
# extraConfig = ''
# client_max_body_size 0;
# '';
# };
# };
# };
"syncthing.swarsel.win" = {
enableACME = true;
forceSSL = true;
acmeRoot = null;
locations = {
"/" = {
proxyPass = "http://localhost:8384/";
proxyPass = "http://localhost:8384";
extraConfig = ''
client_max_body_size 0;
'';
@ -1675,6 +1670,7 @@ This machine mainly acts as an external sync helper. It manages the following th
swarselsystems = lib.recursiveUpdate
{
info = "VM.Standard.A1.Flex, 4 OCPUs, 24GB RAM";
flakePath = "/home/swarsel/.dotfiles";
isImpermanence = true;
isSecureBoot = false;
@ -1929,6 +1925,7 @@ This is a slim setup for developing base configuration. I do not track the hardw
swarselsystems = lib.recursiveUpdate
{
info = "~SwarselSystems~ remote install helper";
wallpaper = self + /wallpaper/lenovowp.png;
isImpermanence = true;
isCrypted = false;
@ -2130,6 +2127,7 @@ Also, an initial bash history is provided to allow for a very quick local deploy
"${self}/modules/iso/minimal.nix"
"${self}/modules/nixos/common/sharedsetup.nix"
"${self}/modules/nixos/common/topology.nix"
"${self}/modules/home/common/sharedsetup.nix"
inputs.home-manager.nixosModules.home-manager
@ -2153,7 +2151,10 @@ Also, an initial bash history is provided to allow for a very quick local deploy
};
};
config = {
node.name = "drugstore";
node.name = lib.mkForce "drugstore";
swarselsystems = {
info = "~SwarselSystems~ installer ISO";
};
home-manager.users."${primaryUser}" = {
home = {
stateVersion = "23.05";
@ -2163,7 +2164,9 @@ Also, an initial bash history is provided to allow for a very quick local deploy
};
};
};
swarselsystems.modules.general = lib.mkForce true;
swarselsystems = {
modules.general = lib.mkForce true;
};
};
home-manager.users.root.home = {
stateVersion = "23.05";
@ -2359,9 +2362,9 @@ I also set the =WLR_RENDERER_ALLOW_SOFTWARE=1= to allow this configuration to ru
firewall.enable = true;
};
swarselsystems = lib.recursiveUpdate
{
info = "~SwarselSystems~ demo host";
wallpaper = self + /wallpaper/lenovowp.png;
initialSetup = true;
isImpermanence = true;
@ -5024,6 +5027,7 @@ TODO
pkgsFor = lib.genAttrs (import systems) (system:
import inputs.nixpkgs {
inherit system;
overlays = [ self.overlays.default ];
config.allowUnfree = true;
}
);
@ -5071,7 +5075,9 @@ TODO
_module.args.primaryUser = linuxUser;
}
] ++
(if (host == "iso") then [ ] else
(if (host == "iso") then [
inputs.nix-topology.nixosModules.default
] else
([
# put nixos imports here that are for all servers and normal hosts
inputs.nix-topology.nixosModules.default
@ -5268,6 +5274,165 @@ in
cat "$out"
fi
#+end_src
**** nix-topology
#+begin_src nix :tangle topology/default.nix
{ config, ... }:
let
inherit (config.lib.topology)
mkInternet
mkDevice
mkSwitch
mkRouter
mkConnection
;
in
{
renderer = "elk";
networks = {
home-lan = {
name = "Home LAN";
cidrv4 = "192.168.1.0/24";
};
wg = {
name = "Wireguard Tunnel";
cidrv4 = "192.168.3.0/24";
};
};
nodes = {
internet = mkInternet {
connections = [
(mkConnection "moonside" "wan")
(mkConnection "pfsense" "wan")
(mkConnection "sync" "wan")
];
};
sync.interfaces.wan = { };
moonside.interfaces.wan = { };
pfsense = mkRouter "pfSense" {
info = "HUNSN RM02";
image = ../topology/images/hunsn.png;
interfaceGroups = [
[
"eth2"
"eth3"
"eth4"
"eth5"
"eth6"
]
[ "wan" ]
];
interfaces.wg0 = {
addresses = [ "192.168.3.1" ];
network = "wg";
virtual = true;
type = "wireguard";
};
connections = {
eth2 = mkConnection "switch-livingroom" "eth1";
eth4 = mkConnection "winters" "eth1";
eth3 = mkConnection "switch-bedroom" "eth1";
eth6 = mkConnection "wifi-ap" "eth1";
wg = mkConnection "moonside" "wg";
};
interfaces = {
eth2 = {
addresses = [ "192.168.1.1" ];
network = "home-lan";
};
eth3 = {
addresses = [ "192.168.1.1" ];
network = "home-lan";
};
eth4 = {
addresses = [ "192.168.1.1" ];
network = "home-lan";
};
eth6 = {
addresses = [ "192.168.1.1" ];
network = "home-lan";
};
};
};
winters.interfaces."eth1" = { };
wifi-ap = mkSwitch "Wi-Fi AP" {
info = "Huawei";
image = ../topology/images/huawei.png;
interfaceGroups = [
[
"eth1"
"wifi"
]
];
};
switch-livingroom = mkSwitch "Switch Livingroom" {
info = "TL-SG108";
image = ../topology/images/TL-SG108.png;
interfaceGroups = [
[
"eth1"
"eth2"
"eth3"
"eth4"
"eth5"
"eth6"
"eth7"
"eth8"
]
];
connections = {
eth2 = mkConnection "nswitch" "eth1";
eth7 = mkConnection "pc" "eth1";
eth8 = mkConnection "nbl-imba-2" "eth1";
};
};
nswitch = mkDevice "Nintendo Switch" {
info = "Nintendo Switch";
image = ../topology/images/nintendo-switch.png;
interfaces.eth1 = { };
};
pc = mkDevice "Windows Gaming Server" {
info = "i7-4790k, GTX970, 32GB RAM";
image = ../topology/images/pc.png;
interfaces.eth1 = { };
};
nbl-imba-2.interfaces.eth1 = { };
switch-bedroom = mkSwitch "Switch Bedroom" {
info = "TL-SG1005D";
image = ../topology/images/TL-SG1005D.png;
interfaceGroups = [
[
"eth1"
"eth2"
"eth3"
"eth4"
"eth5"
]
];
connections.eth2 = mkConnection "printer" "eth1";
};
printer = mkDevice "Printer" {
info = "DELL C2665dnf";
image = ../topology/images/DELL-C2665dnf.png;
interfaces.eth1 = { };
};
};
}
#+end_src
** NixOS
:PROPERTIES:
:CUSTOM_ID: h:6da812f5-358c-49cb-aff2-0a94f20d70b3
@ -5637,6 +5802,8 @@ Mostly used to install some compilers and lsp's that I want to have available wh
zls
ansible-language-server
elk-to-svg
];
nixpkgs.config.permittedInsecurePackages = [
@ -6244,15 +6411,38 @@ Setup timezone and locale. I want to use the US layout, but have the rest adapte
#+begin_src nix :tangle modules/nixos/common/meta.nix
{ lib, ... }:
{
options.node.secretsDir = lib.mkOption {
options = {
node = {
secretsDir = lib.mkOption {
description = "Path to the secrets directory for this node.";
type = lib.types.path;
default = ./.;
};
options.node.name = lib.mkOption {
name = lib.mkOption {
description = "Node Name.";
type = lib.types.str;
};
};
};
}
#+end_src
**** Topology
#+begin_src nix :tangle modules/nixos/common/topology.nix
{ self, lib, config, ... }:
{
options.swarselsystems.info = lib.mkOption {
type = lib.types.str;
default = "";
};
config.topology = {
id = config.node.name;
self = {
hardware.info = config.swarselsystems.info;
icon = lib.mkIf config.swarselsystems.isLaptop "devices.laptop";
};
};
}
#+end_src
@ -7613,7 +7803,7 @@ Here I am forcing =startWhenNeeded= to false so that the value will not be set t
:END:
#+begin_src nix :tangle modules/nixos/server/kavita.nix
{ pkgs, lib, config, ... }:
{ self, lib, config, pkgs, ... }:
let
serviceName = "kavita";
serviceUser = "kavita";
@ -7635,6 +7825,12 @@ Here I am forcing =startWhenNeeded= to false so that the value will not be set t
networking.firewall.allowedTCPPorts = [ 8080 ];
topology.self.services.kavita = {
name = "Kavita";
info = "https://${serviceDomain}";
icon = "${self}/topology/images/kavita.png";
};
services.kavita = {
enable = true;
user = serviceUser;
@ -7701,6 +7897,9 @@ in
libvdpau-va-gl
];
};
topology.self.services.jellyfin.info = "https://${serviceDomain}";
services.jellyfin = {
enable = true;
user = serviceUser;
@ -7969,7 +8168,7 @@ in
:END:
#+begin_src nix :tangle modules/nixos/server/mpd.nix
{ pkgs, lib, config, ... }:
{ self, lib, config, pkgs, ... }:
{
options.swarselsystems.modules.server.mpd = lib.mkEnableOption "enable mpd on server";
config = lib.mkIf config.swarselsystems.modules.server.mpd {
@ -7997,6 +8196,12 @@ in
mpv
];
topology.self.services.mpd = {
name = "MPD";
info = "http://localhost:3254";
icon = "${self}/topology/images/mpd.png";
};
services.mpd = {
enable = true;
musicDirectory = "/media";
@ -8498,6 +8703,8 @@ in
extraGroups = [ "video" "render" "users" ];
};
topology.self.services.immich.info = "https://${serviceDomain}";
services.immich = {
enable = true;
host = "0.0.0.0";
@ -8694,7 +8901,10 @@ Also I install Tika and Gotenberg, which are needed to create PDFs out of =.eml=
:END:
#+begin_src nix :tangle modules/nixos/server/transmission.nix
{ pkgs, lib, config, ... }:
{ self, pkgs, lib, config, ... }:
let
serviceDomain = "store.swarsel.win";
in
{
options.swarselsystems.modules.server.transmission = lib.mkEnableOption "enable transmission and friends on server";
config = lib.mkIf config.swarselsystems.modules.server.transmission {
@ -8751,6 +8961,18 @@ Also I install Tika and Gotenberg, which are needed to create PDFs out of =.eml=
docker
];
topology.self.services = {
radarr.info = "https://${serviceDomain}/radarr";
readarr = {
name = "Readarr";
info = "https://${serviceDomain}/readarr";
icon = "${self}/topology/images/readarr.png";
};
sonarr.info = "https://${serviceDomain}/sonarr";
lidarr.info = "https://${serviceDomain}/lidarr";
prowlarr.info = "https://${serviceDomain}/prowlarr";
};
services = {
radarr = {
enable = true;
@ -9073,6 +9295,8 @@ This section exposes several metrics that I use to check the health of my server
networking.firewall.allowedTCPPorts = [ servicePort prometheusPort ];
topology.self.services.prometheus.info = "https://${serviceDomain}/${prometheusWebRoot}";
services = {
grafana = {
enable = true;
@ -9342,9 +9566,10 @@ I am using this with CapyReader on my phone, set it up as a FreshRSS account wit
FreshRSS claims to support HTTP header auth, but at least it does not work with my oauth2-proxy setup. Until this is fixed, I resorted to the "form" login, since I mostly do not use the web version anyways.
#+begin_src nix :tangle modules/nixos/server/freshrss.nix
{ lib, config, ... }:
{ self, lib, config, ... }:
let
serviceName = "freshrss";
serviceDomain = "signpost.swarsel.win";
in
{
options.swarselsystems.modules.server.freshrss = lib.mkEnableOption "enable freshrss on server";
@ -9385,10 +9610,16 @@ FreshRSS claims to support HTTP header auth, but at least it does not work with
# };
};
topology.self.services.freshrss = {
name = "FreshRSS";
info = "https://${serviceDomain}";
icon = "${self}/topology/images/freshrss.png";
};
services.freshrss = {
enable = true;
virtualHost = "signpost.swarsel.win";
baseUrl = "https://signpost.swarsel.win";
virtualHost = serviceDomain;
baseUrl = "https://${serviceDomain}";
authType = "form";
dataDir = "/Vault/data/tt-rss";
defaultUser = "Swarsel";
@ -9408,7 +9639,7 @@ FreshRSS claims to support HTTP header auth, but at least it does not work with
};
};
virtualHosts = {
"signpost.swarsel.win" = {
"${serviceDomain}" = {
enableACME = true;
forceSSL = true;
acmeRoot = null;
@ -9454,6 +9685,9 @@ FreshRSS claims to support HTTP header auth, but at least it does not work with
proxy_pass_request_body off;
'';
};
"/api" = {
proxyPass = "http://${serviceName}";
};
};
};
};
@ -9621,6 +9855,9 @@ FreshRSS claims to support HTTP header auth, but at least it does not work with
#+begin_src nix :tangle modules/nixos/server/ankisync.nix
{ lib, config, ... }:
let
serviceDomain = "synki.swarsel.win";
in
{
options.swarselsystems.modules.server.ankisync = lib.mkEnableOption "enable ankisync on server";
config = lib.mkIf config.swarselsystems.modules.server.ankisync {
@ -9629,6 +9866,11 @@ FreshRSS claims to support HTTP header auth, but at least it does not work with
sops.secrets.swarsel = { owner = "root"; };
topology.self.services.anki = {
name = lib.mkForce "Anki Sync Server";
info = "https://${serviceDomain}";
};
services.anki-sync-server = {
enable = true;
port = 27701;
@ -9644,7 +9886,7 @@ FreshRSS claims to support HTTP header auth, but at least it does not work with
services.nginx = {
virtualHosts = {
"synki.swarsel.win" = {
"${serviceDomain}" = {
enableACME = true;
forceSSL = true;
acmeRoot = null;
@ -10029,7 +10271,7 @@ To get other URLs (token, etc.), use https://<kanidmDomain>/oauth2/openid/<clien
**** Firefly-III
#+begin_src nix :tangle modules/nixos/server/firefly-iii.nix
{ lib, config, ... }:
{ self, lib, config, ... }:
let
cfg = config.services.firefly-iii;
fireflyDomain = "stonks.swarsel.win";
@ -10051,6 +10293,12 @@ To get other URLs (token, etc.), use https://<kanidmDomain>/oauth2/openid/<clien
};
};
topology.self.services.firefly-iii = {
name = "Firefly-III";
info = "https://${fireflyDomain}";
icon = "${self}/topology/images/firefly-iii.png";
};
services = {
firefly-iii = {
enable = true;
@ -10162,7 +10410,7 @@ To get other URLs (token, etc.), use https://<kanidmDomain>/oauth2/openid/<clien
**** Koillection
#+begin_src nix :tangle modules/nixos/server/koillection.nix
{ lib, config, ... }:
{ self, lib, config, ... }:
let
serviceDomain = "swag.swarsel.win";
serviceUser = "koillection";
@ -10182,6 +10430,12 @@ To get other URLs (token, etc.), use https://<kanidmDomain>/oauth2/openid/<clien
koillection-env-file = { };
};
topology.self.services.koillection = {
name = "Koillection";
info = "https://${serviceDomain}";
icon = "${self}/topology/images/koillection.png";
};
virtualisation.oci-containers.containers = {
koillection = {
image = "koillection/koillection@${containerRev}";

View file

@ -199,8 +199,7 @@
lib.swarselsystems.forEachSystem (pkgs: import inputs.nix-topology {
inherit pkgs;
modules = [
# Your own file to define global topology. Works in principle like a nixos module but uses different options.
# ./topology.nix
"${self}/topology"
{ inherit (self) nixosConfigurations; }
];
});

View file

@ -45,9 +45,9 @@ in
firewall.enable = true;
};
swarselsystems = lib.recursiveUpdate
{
info = "~SwarselSystems~ demo host";
wallpaper = self + /wallpaper/lenovowp.png;
initialSetup = true;
isImpermanence = true;

View file

@ -10,6 +10,7 @@ in
"${self}/modules/iso/minimal.nix"
"${self}/modules/nixos/common/sharedsetup.nix"
"${self}/modules/nixos/common/topology.nix"
"${self}/modules/home/common/sharedsetup.nix"
inputs.home-manager.nixosModules.home-manager
@ -33,7 +34,10 @@ in
};
};
config = {
node.name = "drugstore";
node.name = lib.mkForce "drugstore";
swarselsystems = {
info = "~SwarselSystems~ installer ISO";
};
home-manager.users."${primaryUser}" = {
home = {
stateVersion = "23.05";
@ -43,7 +47,9 @@ in
};
};
};
swarselsystems.modules.general = lib.mkForce true;
swarselsystems = {
modules.general = lib.mkForce true;
};
};
home-manager.users.root.home = {
stateVersion = "23.05";

View file

@ -39,6 +39,12 @@ in
];
};
topology.self.interfaces.wg = {
addresses = [ "192.168.3.4" ];
renderer.hidePhysicalConnections = true;
virtual = true;
type = "wireguard";
};
networking = {
nftables.enable = lib.mkForce false;
@ -80,26 +86,13 @@ in
services = {
nginx = {
virtualHosts = {
# "newway.swarsel.win" = {
# enableACME = true;
# forceSSL = true;
# acmeRoot = null;
# locations = {
# "/" = {
# proxyPass = "http://192.168.1.2:8080";
# extraConfig = ''
# client_max_body_size 0;
# '';
# };
# };
# };
"syncthing.swarsel.win" = {
enableACME = true;
forceSSL = true;
acmeRoot = null;
locations = {
"/" = {
proxyPass = "http://localhost:8384/";
proxyPass = "http://localhost:8384";
extraConfig = ''
client_max_body_size 0;
'';
@ -221,6 +214,7 @@ in
swarselsystems = lib.recursiveUpdate
{
info = "VM.Standard.A1.Flex, 4 OCPUs, 24GB RAM";
flakePath = "/home/swarsel/.dotfiles";
isImpermanence = true;
isSecureBoot = false;

View file

@ -24,6 +24,7 @@ in
swarselsystems = lib.recursiveUpdate
{
info = "Framework Laptop 16, 7940HS, RX7700S, 64GB RAM";
firewall = lib.mkForce true;
wallpaper = self + /wallpaper/lenovowp.png;
hasBluetooth = true;

View file

@ -60,7 +60,7 @@ in
acmeRoot = null;
locations = {
"/" = {
proxyPass = "http://localhost:8384/";
proxyPass = "http://localhost:8384";
extraConfig = ''
client_max_body_size 0;
'';
@ -152,6 +152,7 @@ in
swarselsystems = lib.recursiveUpdate
{
info = "VM.Standard.E2.1.Micro";
flakePath = "/root/.dotfiles";
isImpermanence = false;
isSecureBoot = false;

View file

@ -57,6 +57,7 @@ in
swarselsystems = lib.recursiveUpdate
{
info = "~SwarselSystems~ remote install helper";
wallpaper = self + /wallpaper/lenovowp.png;
isImpermanence = true;
isCrypted = false;

View file

@ -30,6 +30,7 @@ in
swarselsystems = lib.recursiveUpdate
{
info = "ASRock J4105-ITX, 32GB RAM";
isImpermanence = false;
isSecureBoot = true;
isCrypted = true;

2109
index.html

File diff suppressed because it is too large Load diff

View file

@ -22,6 +22,7 @@ in
pkgsFor = lib.genAttrs (import systems) (system:
import inputs.nixpkgs {
inherit system;
overlays = [ self.overlays.default ];
config.allowUnfree = true;
}
);
@ -69,7 +70,9 @@ in
_module.args.primaryUser = linuxUser;
}
] ++
(if (host == "iso") then [ ] else
(if (host == "iso") then [
inputs.nix-topology.nixosModules.default
] else
([
# put nixos imports here that are for all servers and normal hosts
inputs.nix-topology.nixosModules.default

View file

@ -1,12 +1,16 @@
{ lib, ... }:
{
options.node.secretsDir = lib.mkOption {
options = {
node = {
secretsDir = lib.mkOption {
description = "Path to the secrets directory for this node.";
type = lib.types.path;
default = ./.;
};
options.node.name = lib.mkOption {
name = lib.mkOption {
description = "Node Name.";
type = lib.types.str;
};
};
};
}

View file

@ -72,6 +72,8 @@
zls
ansible-language-server
elk-to-svg
];
nixpkgs.config.permittedInsecurePackages = [

View file

@ -0,0 +1,14 @@
{ self, lib, config, ... }:
{
options.swarselsystems.info = lib.mkOption {
type = lib.types.str;
default = "";
};
config.topology = {
id = config.node.name;
self = {
hardware.info = config.swarselsystems.info;
icon = lib.mkIf config.swarselsystems.isLaptop "devices.laptop";
};
};
}

View file

@ -1,4 +1,7 @@
{ lib, config, ... }:
let
serviceDomain = "synki.swarsel.win";
in
{
options.swarselsystems.modules.server.ankisync = lib.mkEnableOption "enable ankisync on server";
config = lib.mkIf config.swarselsystems.modules.server.ankisync {
@ -7,6 +10,11 @@
sops.secrets.swarsel = { owner = "root"; };
topology.self.services.anki = {
name = lib.mkForce "Anki Sync Server";
info = "https://${serviceDomain}";
};
services.anki-sync-server = {
enable = true;
port = 27701;
@ -22,7 +30,7 @@
services.nginx = {
virtualHosts = {
"synki.swarsel.win" = {
"${serviceDomain}" = {
enableACME = true;
forceSSL = true;
acmeRoot = null;

View file

@ -1,4 +1,4 @@
{ lib, config, ... }:
{ self, lib, config, ... }:
let
cfg = config.services.firefly-iii;
fireflyDomain = "stonks.swarsel.win";
@ -20,6 +20,12 @@ in
};
};
topology.self.services.firefly-iii = {
name = "Firefly-III";
info = "https://${fireflyDomain}";
icon = "${self}/topology/images/firefly-iii.png";
};
services = {
firefly-iii = {
enable = true;

View file

@ -1,6 +1,7 @@
{ lib, config, ... }:
{ self, lib, config, ... }:
let
serviceName = "freshrss";
serviceDomain = "signpost.swarsel.win";
in
{
options.swarselsystems.modules.server.freshrss = lib.mkEnableOption "enable freshrss on server";
@ -41,10 +42,16 @@ in
# };
};
topology.self.services.freshrss = {
name = "FreshRSS";
info = "https://${serviceDomain}";
icon = "${self}/topology/images/freshrss.png";
};
services.freshrss = {
enable = true;
virtualHost = "signpost.swarsel.win";
baseUrl = "https://signpost.swarsel.win";
virtualHost = serviceDomain;
baseUrl = "https://${serviceDomain}";
authType = "form";
dataDir = "/Vault/data/tt-rss";
defaultUser = "Swarsel";
@ -64,7 +71,7 @@ in
};
};
virtualHosts = {
"signpost.swarsel.win" = {
"${serviceDomain}" = {
enableACME = true;
forceSSL = true;
acmeRoot = null;
@ -110,6 +117,9 @@ in
proxy_pass_request_body off;
'';
};
"/api" = {
proxyPass = "http://${serviceName}";
};
};
};
};

View file

@ -13,6 +13,8 @@ in
extraGroups = [ "video" "render" "users" ];
};
topology.self.services.immich.info = "https://${serviceDomain}";
services.immich = {
enable = true;
host = "0.0.0.0";

View file

@ -23,6 +23,9 @@ in
libvdpau-va-gl
];
};
topology.self.services.jellyfin.info = "https://${serviceDomain}";
services.jellyfin = {
enable = true;
user = serviceUser;

View file

@ -1,4 +1,4 @@
{ pkgs, lib, config, ... }:
{ self, lib, config, pkgs, ... }:
let
serviceName = "kavita";
serviceUser = "kavita";
@ -20,6 +20,12 @@ in
networking.firewall.allowedTCPPorts = [ 8080 ];
topology.self.services.kavita = {
name = "Kavita";
info = "https://${serviceDomain}";
icon = "${self}/topology/images/kavita.png";
};
services.kavita = {
enable = true;
user = serviceUser;

View file

@ -1,4 +1,4 @@
{ lib, config, ... }:
{ self, lib, config, ... }:
let
serviceDomain = "swag.swarsel.win";
serviceUser = "koillection";
@ -18,6 +18,12 @@ in
koillection-env-file = { };
};
topology.self.services.koillection = {
name = "Koillection";
info = "https://${serviceDomain}";
icon = "${self}/topology/images/koillection.png";
};
virtualisation.oci-containers.containers = {
koillection = {
image = "koillection/koillection@${containerRev}";

View file

@ -34,6 +34,8 @@ in
networking.firewall.allowedTCPPorts = [ servicePort prometheusPort ];
topology.self.services.prometheus.info = "https://${serviceDomain}/${prometheusWebRoot}";
services = {
grafana = {
enable = true;

View file

@ -1,4 +1,4 @@
{ pkgs, lib, config, ... }:
{ self, lib, config, pkgs, ... }:
{
options.swarselsystems.modules.server.mpd = lib.mkEnableOption "enable mpd on server";
config = lib.mkIf config.swarselsystems.modules.server.mpd {
@ -26,6 +26,12 @@
mpv
];
topology.self.services.mpd = {
name = "MPD";
info = "http://localhost:3254";
icon = "${self}/topology/images/mpd.png";
};
services.mpd = {
enable = true;
musicDirectory = "/media";

View file

@ -1,4 +1,7 @@
{ pkgs, lib, config, ... }:
{ self, pkgs, lib, config, ... }:
let
serviceDomain = "store.swarsel.win";
in
{
options.swarselsystems.modules.server.transmission = lib.mkEnableOption "enable transmission and friends on server";
config = lib.mkIf config.swarselsystems.modules.server.transmission {
@ -55,6 +58,18 @@
docker
];
topology.self.services = {
radarr.info = "https://${serviceDomain}/radarr";
readarr = {
name = "Readarr";
info = "https://${serviceDomain}/readarr";
icon = "${self}/topology/images/readarr.png";
};
sonarr.info = "https://${serviceDomain}/sonarr";
lidarr.info = "https://${serviceDomain}/lidarr";
prowlarr.info = "https://${serviceDomain}/prowlarr";
};
services = {
radarr = {
enable = true;

154
topology/default.nix Normal file
View file

@ -0,0 +1,154 @@
{ config, ... }:
let
inherit (config.lib.topology)
mkInternet
mkDevice
mkSwitch
mkRouter
mkConnection
;
in
{
renderer = "elk";
networks = {
home-lan = {
name = "Home LAN";
cidrv4 = "192.168.1.0/24";
};
wg = {
name = "Wireguard Tunnel";
cidrv4 = "192.168.3.0/24";
};
};
nodes = {
internet = mkInternet {
connections = [
(mkConnection "moonside" "wan")
(mkConnection "pfsense" "wan")
(mkConnection "sync" "wan")
];
};
sync.interfaces.wan = { };
moonside.interfaces.wan = { };
pfsense = mkRouter "pfSense" {
info = "HUNSN RM02";
image = ../topology/images/hunsn.png;
interfaceGroups = [
[
"eth2"
"eth3"
"eth4"
"eth5"
"eth6"
]
[ "wan" ]
];
interfaces.wg0 = {
addresses = [ "192.168.3.1" ];
network = "wg";
virtual = true;
type = "wireguard";
};
connections = {
eth2 = mkConnection "switch-livingroom" "eth1";
eth4 = mkConnection "winters" "eth1";
eth3 = mkConnection "switch-bedroom" "eth1";
eth6 = mkConnection "wifi-ap" "eth1";
wg = mkConnection "moonside" "wg";
};
interfaces = {
eth2 = {
addresses = [ "192.168.1.1" ];
network = "home-lan";
};
eth3 = {
addresses = [ "192.168.1.1" ];
network = "home-lan";
};
eth4 = {
addresses = [ "192.168.1.1" ];
network = "home-lan";
};
eth6 = {
addresses = [ "192.168.1.1" ];
network = "home-lan";
};
};
};
winters.interfaces."eth1" = { };
wifi-ap = mkSwitch "Wi-Fi AP" {
info = "Huawei";
image = ../topology/images/huawei.png;
interfaceGroups = [
[
"eth1"
"wifi"
]
];
};
switch-livingroom = mkSwitch "Switch Livingroom" {
info = "TL-SG108";
image = ../topology/images/TL-SG108.png;
interfaceGroups = [
[
"eth1"
"eth2"
"eth3"
"eth4"
"eth5"
"eth6"
"eth7"
"eth8"
]
];
connections = {
eth2 = mkConnection "nswitch" "eth1";
eth7 = mkConnection "pc" "eth1";
eth8 = mkConnection "nbl-imba-2" "eth1";
};
};
nswitch = mkDevice "Nintendo Switch" {
info = "Nintendo Switch";
image = ../topology/images/nintendo-switch.png;
interfaces.eth1 = { };
};
pc = mkDevice "Windows Gaming Server" {
info = "i7-4790k, GTX970, 32GB RAM";
image = ../topology/images/pc.png;
interfaces.eth1 = { };
};
nbl-imba-2.interfaces.eth1 = { };
switch-bedroom = mkSwitch "Switch Bedroom" {
info = "TL-SG1005D";
image = ../topology/images/TL-SG1005D.png;
interfaceGroups = [
[
"eth1"
"eth2"
"eth3"
"eth4"
"eth5"
]
];
connections.eth2 = mkConnection "printer" "eth1";
};
printer = mkDevice "Printer" {
info = "DELL C2665dnf";
image = ../topology/images/DELL-C2665dnf.png;
interfaces.eth1 = { };
};
};
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 122 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 393 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 139 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 90 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

BIN
topology/images/huawei.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 157 KiB

BIN
topology/images/hunsn.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 205 KiB

BIN
topology/images/kavita.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 23 KiB

BIN
topology/images/mpd.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 84 KiB

BIN
topology/images/pc.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 107 KiB

BIN
topology/images/readarr.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB