feat: full nix-topology
|
|
@ -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 {
|
lib.swarselsystems.forEachSystem (pkgs: import inputs.nix-topology {
|
||||||
inherit pkgs;
|
inherit pkgs;
|
||||||
modules = [
|
modules = [
|
||||||
# Your own file to define global topology. Works in principle like a nixos module but uses different options.
|
"${self}/topology"
|
||||||
# ./topology.nix
|
|
||||||
{ inherit (self) nixosConfigurations; }
|
{ 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
|
swarselsystems = lib.recursiveUpdate
|
||||||
{
|
{
|
||||||
|
info = "Framework Laptop 16, 7940HS, RX7700S, 64GB RAM";
|
||||||
firewall = lib.mkForce true;
|
firewall = lib.mkForce true;
|
||||||
wallpaper = self + /wallpaper/lenovowp.png;
|
wallpaper = self + /wallpaper/lenovowp.png;
|
||||||
hasBluetooth = true;
|
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
|
swarselsystems = lib.recursiveUpdate
|
||||||
{
|
{
|
||||||
|
info = "ASRock J4105-ITX, 32GB RAM";
|
||||||
isImpermanence = false;
|
isImpermanence = false;
|
||||||
isSecureBoot = true;
|
isSecureBoot = true;
|
||||||
isCrypted = true;
|
isCrypted = true;
|
||||||
|
|
@ -1336,7 +1337,7 @@ This machine mainly acts as an external sync helper. It manages the following th
|
||||||
acmeRoot = null;
|
acmeRoot = null;
|
||||||
locations = {
|
locations = {
|
||||||
"/" = {
|
"/" = {
|
||||||
proxyPass = "http://localhost:8384/";
|
proxyPass = "http://localhost:8384";
|
||||||
extraConfig = ''
|
extraConfig = ''
|
||||||
client_max_body_size 0;
|
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
|
swarselsystems = lib.recursiveUpdate
|
||||||
{
|
{
|
||||||
|
info = "VM.Standard.E2.1.Micro";
|
||||||
flakePath = "/root/.dotfiles";
|
flakePath = "/root/.dotfiles";
|
||||||
isImpermanence = false;
|
isImpermanence = false;
|
||||||
isSecureBoot = 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 = {
|
networking = {
|
||||||
nftables.enable = lib.mkForce false;
|
nftables.enable = lib.mkForce false;
|
||||||
|
|
@ -1534,26 +1542,13 @@ This machine mainly acts as an external sync helper. It manages the following th
|
||||||
services = {
|
services = {
|
||||||
nginx = {
|
nginx = {
|
||||||
virtualHosts = {
|
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" = {
|
"syncthing.swarsel.win" = {
|
||||||
enableACME = true;
|
enableACME = true;
|
||||||
forceSSL = true;
|
forceSSL = true;
|
||||||
acmeRoot = null;
|
acmeRoot = null;
|
||||||
locations = {
|
locations = {
|
||||||
"/" = {
|
"/" = {
|
||||||
proxyPass = "http://localhost:8384/";
|
proxyPass = "http://localhost:8384";
|
||||||
extraConfig = ''
|
extraConfig = ''
|
||||||
client_max_body_size 0;
|
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
|
swarselsystems = lib.recursiveUpdate
|
||||||
{
|
{
|
||||||
|
info = "VM.Standard.A1.Flex, 4 OCPUs, 24GB RAM";
|
||||||
flakePath = "/home/swarsel/.dotfiles";
|
flakePath = "/home/swarsel/.dotfiles";
|
||||||
isImpermanence = true;
|
isImpermanence = true;
|
||||||
isSecureBoot = false;
|
isSecureBoot = false;
|
||||||
|
|
@ -1929,6 +1925,7 @@ This is a slim setup for developing base configuration. I do not track the hardw
|
||||||
|
|
||||||
swarselsystems = lib.recursiveUpdate
|
swarselsystems = lib.recursiveUpdate
|
||||||
{
|
{
|
||||||
|
info = "~SwarselSystems~ remote install helper";
|
||||||
wallpaper = self + /wallpaper/lenovowp.png;
|
wallpaper = self + /wallpaper/lenovowp.png;
|
||||||
isImpermanence = true;
|
isImpermanence = true;
|
||||||
isCrypted = false;
|
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/iso/minimal.nix"
|
||||||
"${self}/modules/nixos/common/sharedsetup.nix"
|
"${self}/modules/nixos/common/sharedsetup.nix"
|
||||||
|
"${self}/modules/nixos/common/topology.nix"
|
||||||
"${self}/modules/home/common/sharedsetup.nix"
|
"${self}/modules/home/common/sharedsetup.nix"
|
||||||
|
|
||||||
inputs.home-manager.nixosModules.home-manager
|
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 = {
|
config = {
|
||||||
node.name = "drugstore";
|
node.name = lib.mkForce "drugstore";
|
||||||
|
swarselsystems = {
|
||||||
|
info = "~SwarselSystems~ installer ISO";
|
||||||
|
};
|
||||||
home-manager.users."${primaryUser}" = {
|
home-manager.users."${primaryUser}" = {
|
||||||
home = {
|
home = {
|
||||||
stateVersion = "23.05";
|
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 = {
|
home-manager.users.root.home = {
|
||||||
stateVersion = "23.05";
|
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;
|
firewall.enable = true;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
swarselsystems = lib.recursiveUpdate
|
swarselsystems = lib.recursiveUpdate
|
||||||
{
|
{
|
||||||
|
info = "~SwarselSystems~ demo host";
|
||||||
wallpaper = self + /wallpaper/lenovowp.png;
|
wallpaper = self + /wallpaper/lenovowp.png;
|
||||||
initialSetup = true;
|
initialSetup = true;
|
||||||
isImpermanence = true;
|
isImpermanence = true;
|
||||||
|
|
@ -5024,6 +5027,7 @@ TODO
|
||||||
pkgsFor = lib.genAttrs (import systems) (system:
|
pkgsFor = lib.genAttrs (import systems) (system:
|
||||||
import inputs.nixpkgs {
|
import inputs.nixpkgs {
|
||||||
inherit system;
|
inherit system;
|
||||||
|
overlays = [ self.overlays.default ];
|
||||||
config.allowUnfree = true;
|
config.allowUnfree = true;
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
@ -5071,7 +5075,9 @@ TODO
|
||||||
_module.args.primaryUser = linuxUser;
|
_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
|
# put nixos imports here that are for all servers and normal hosts
|
||||||
inputs.nix-topology.nixosModules.default
|
inputs.nix-topology.nixosModules.default
|
||||||
|
|
@ -5268,6 +5274,165 @@ in
|
||||||
cat "$out"
|
cat "$out"
|
||||||
fi
|
fi
|
||||||
#+end_src
|
#+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
|
** NixOS
|
||||||
:PROPERTIES:
|
:PROPERTIES:
|
||||||
:CUSTOM_ID: h:6da812f5-358c-49cb-aff2-0a94f20d70b3
|
: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
|
zls
|
||||||
ansible-language-server
|
ansible-language-server
|
||||||
|
|
||||||
|
elk-to-svg
|
||||||
|
|
||||||
];
|
];
|
||||||
|
|
||||||
nixpkgs.config.permittedInsecurePackages = [
|
nixpkgs.config.permittedInsecurePackages = [
|
||||||
|
|
@ -6244,14 +6411,37 @@ 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
|
#+begin_src nix :tangle modules/nixos/common/meta.nix
|
||||||
{ lib, ... }:
|
{ lib, ... }:
|
||||||
{
|
{
|
||||||
options.node.secretsDir = lib.mkOption {
|
options = {
|
||||||
description = "Path to the secrets directory for this node.";
|
node = {
|
||||||
type = lib.types.path;
|
secretsDir = lib.mkOption {
|
||||||
default = ./.;
|
description = "Path to the secrets directory for this node.";
|
||||||
|
type = lib.types.path;
|
||||||
|
default = ./.;
|
||||||
|
};
|
||||||
|
name = lib.mkOption {
|
||||||
|
description = "Node Name.";
|
||||||
|
type = lib.types.str;
|
||||||
|
};
|
||||||
|
};
|
||||||
};
|
};
|
||||||
options.node.name = lib.mkOption {
|
}
|
||||||
description = "Node Name.";
|
#+end_src
|
||||||
|
|
||||||
|
**** Topology
|
||||||
|
|
||||||
|
#+begin_src nix :tangle modules/nixos/common/topology.nix
|
||||||
|
{ self, lib, config, ... }:
|
||||||
|
{
|
||||||
|
options.swarselsystems.info = lib.mkOption {
|
||||||
type = lib.types.str;
|
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
|
#+end_src
|
||||||
|
|
@ -7613,7 +7803,7 @@ Here I am forcing =startWhenNeeded= to false so that the value will not be set t
|
||||||
:END:
|
:END:
|
||||||
|
|
||||||
#+begin_src nix :tangle modules/nixos/server/kavita.nix
|
#+begin_src nix :tangle modules/nixos/server/kavita.nix
|
||||||
{ pkgs, lib, config, ... }:
|
{ self, lib, config, pkgs, ... }:
|
||||||
let
|
let
|
||||||
serviceName = "kavita";
|
serviceName = "kavita";
|
||||||
serviceUser = "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 ];
|
networking.firewall.allowedTCPPorts = [ 8080 ];
|
||||||
|
|
||||||
|
topology.self.services.kavita = {
|
||||||
|
name = "Kavita";
|
||||||
|
info = "https://${serviceDomain}";
|
||||||
|
icon = "${self}/topology/images/kavita.png";
|
||||||
|
};
|
||||||
|
|
||||||
services.kavita = {
|
services.kavita = {
|
||||||
enable = true;
|
enable = true;
|
||||||
user = serviceUser;
|
user = serviceUser;
|
||||||
|
|
@ -7676,64 +7872,67 @@ Here I am forcing =startWhenNeeded= to false so that the value will not be set t
|
||||||
:END:
|
:END:
|
||||||
|
|
||||||
#+begin_src nix :tangle modules/nixos/server/jellyfin.nix
|
#+begin_src nix :tangle modules/nixos/server/jellyfin.nix
|
||||||
{ pkgs, lib, config, ... }:
|
{ pkgs, lib, config, ... }:
|
||||||
let
|
let
|
||||||
serviceDomain = "screen.swarsel.win";
|
serviceDomain = "screen.swarsel.win";
|
||||||
servicePort = 8096;
|
servicePort = 8096;
|
||||||
serviceName = "jellyfin";
|
serviceName = "jellyfin";
|
||||||
serviceUser = "jellyfin";
|
serviceUser = "jellyfin";
|
||||||
in
|
in
|
||||||
{
|
{
|
||||||
options.swarselsystems.modules.server."${serviceName}" = lib.mkEnableOption "enable ${serviceName} on server";
|
options.swarselsystems.modules.server."${serviceName}" = lib.mkEnableOption "enable ${serviceName} on server";
|
||||||
config = lib.mkIf config.swarselsystems.modules.server."${serviceName}" {
|
config = lib.mkIf config.swarselsystems.modules.server."${serviceName}" {
|
||||||
users.users."${serviceUser}" = {
|
users.users."${serviceUser}" = {
|
||||||
extraGroups = [ "video" "render" "users" ];
|
extraGroups = [ "video" "render" "users" ];
|
||||||
};
|
};
|
||||||
nixpkgs.config.packageOverrides = pkgs: {
|
nixpkgs.config.packageOverrides = pkgs: {
|
||||||
vaapiIntel = pkgs.vaapiIntel.override { enableHybridCodec = true; };
|
vaapiIntel = pkgs.vaapiIntel.override { enableHybridCodec = true; };
|
||||||
};
|
};
|
||||||
hardware.graphics = {
|
hardware.graphics = {
|
||||||
enable = true;
|
enable = true;
|
||||||
extraPackages = with pkgs; [
|
extraPackages = with pkgs; [
|
||||||
intel-media-driver # LIBVA_DRIVER_NAME=iHD
|
intel-media-driver # LIBVA_DRIVER_NAME=iHD
|
||||||
vaapiIntel # LIBVA_DRIVER_NAME=i965 (older but works better for Firefox/Chromium)
|
vaapiIntel # LIBVA_DRIVER_NAME=i965 (older but works better for Firefox/Chromium)
|
||||||
vaapiVdpau
|
vaapiVdpau
|
||||||
libvdpau-va-gl
|
libvdpau-va-gl
|
||||||
];
|
];
|
||||||
};
|
};
|
||||||
services.jellyfin = {
|
|
||||||
enable = true;
|
|
||||||
user = serviceUser;
|
|
||||||
openFirewall = true; # this works only for the default ports
|
|
||||||
};
|
|
||||||
|
|
||||||
nodes.moonside.services.nginx = {
|
topology.self.services.jellyfin.info = "https://${serviceDomain}";
|
||||||
upstreams = {
|
|
||||||
"${serviceName}" = {
|
services.jellyfin = {
|
||||||
servers = {
|
enable = true;
|
||||||
"192.168.1.2:${builtins.toString servicePort}" = { };
|
user = serviceUser;
|
||||||
|
openFirewall = true; # this works only for the default ports
|
||||||
|
};
|
||||||
|
|
||||||
|
nodes.moonside.services.nginx = {
|
||||||
|
upstreams = {
|
||||||
|
"${serviceName}" = {
|
||||||
|
servers = {
|
||||||
|
"192.168.1.2:${builtins.toString servicePort}" = { };
|
||||||
|
};
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
};
|
virtualHosts = {
|
||||||
virtualHosts = {
|
"${serviceDomain}" = {
|
||||||
"${serviceDomain}" = {
|
enableACME = true;
|
||||||
enableACME = true;
|
forceSSL = true;
|
||||||
forceSSL = true;
|
acmeRoot = null;
|
||||||
acmeRoot = null;
|
locations = {
|
||||||
locations = {
|
"/" = {
|
||||||
"/" = {
|
proxyPass = "http://${serviceName}";
|
||||||
proxyPass = "http://${serviceName}";
|
extraConfig = ''
|
||||||
extraConfig = ''
|
client_max_body_size 0;
|
||||||
client_max_body_size 0;
|
'';
|
||||||
'';
|
};
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
};
|
|
||||||
|
|
||||||
}
|
}
|
||||||
#+end_src
|
#+end_src
|
||||||
|
|
||||||
**** navidrome
|
**** navidrome
|
||||||
|
|
@ -7969,7 +8168,7 @@ in
|
||||||
:END:
|
:END:
|
||||||
|
|
||||||
#+begin_src nix :tangle modules/nixos/server/mpd.nix
|
#+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";
|
options.swarselsystems.modules.server.mpd = lib.mkEnableOption "enable mpd on server";
|
||||||
config = lib.mkIf config.swarselsystems.modules.server.mpd {
|
config = lib.mkIf config.swarselsystems.modules.server.mpd {
|
||||||
|
|
@ -7997,6 +8196,12 @@ in
|
||||||
mpv
|
mpv
|
||||||
];
|
];
|
||||||
|
|
||||||
|
topology.self.services.mpd = {
|
||||||
|
name = "MPD";
|
||||||
|
info = "http://localhost:3254";
|
||||||
|
icon = "${self}/topology/images/mpd.png";
|
||||||
|
};
|
||||||
|
|
||||||
services.mpd = {
|
services.mpd = {
|
||||||
enable = true;
|
enable = true;
|
||||||
musicDirectory = "/media";
|
musicDirectory = "/media";
|
||||||
|
|
@ -8498,6 +8703,8 @@ in
|
||||||
extraGroups = [ "video" "render" "users" ];
|
extraGroups = [ "video" "render" "users" ];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
topology.self.services.immich.info = "https://${serviceDomain}";
|
||||||
|
|
||||||
services.immich = {
|
services.immich = {
|
||||||
enable = true;
|
enable = true;
|
||||||
host = "0.0.0.0";
|
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:
|
:END:
|
||||||
|
|
||||||
#+begin_src nix :tangle modules/nixos/server/transmission.nix
|
#+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";
|
options.swarselsystems.modules.server.transmission = lib.mkEnableOption "enable transmission and friends on server";
|
||||||
config = lib.mkIf config.swarselsystems.modules.server.transmission {
|
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
|
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 = {
|
services = {
|
||||||
radarr = {
|
radarr = {
|
||||||
enable = true;
|
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 ];
|
networking.firewall.allowedTCPPorts = [ servicePort prometheusPort ];
|
||||||
|
|
||||||
|
topology.self.services.prometheus.info = "https://${serviceDomain}/${prometheusWebRoot}";
|
||||||
|
|
||||||
services = {
|
services = {
|
||||||
grafana = {
|
grafana = {
|
||||||
enable = true;
|
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.
|
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
|
#+begin_src nix :tangle modules/nixos/server/freshrss.nix
|
||||||
{ lib, config, ... }:
|
{ self, lib, config, ... }:
|
||||||
let
|
let
|
||||||
serviceName = "freshrss";
|
serviceName = "freshrss";
|
||||||
|
serviceDomain = "signpost.swarsel.win";
|
||||||
in
|
in
|
||||||
{
|
{
|
||||||
options.swarselsystems.modules.server.freshrss = lib.mkEnableOption "enable freshrss on server";
|
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 = {
|
services.freshrss = {
|
||||||
enable = true;
|
enable = true;
|
||||||
virtualHost = "signpost.swarsel.win";
|
virtualHost = serviceDomain;
|
||||||
baseUrl = "https://signpost.swarsel.win";
|
baseUrl = "https://${serviceDomain}";
|
||||||
authType = "form";
|
authType = "form";
|
||||||
dataDir = "/Vault/data/tt-rss";
|
dataDir = "/Vault/data/tt-rss";
|
||||||
defaultUser = "Swarsel";
|
defaultUser = "Swarsel";
|
||||||
|
|
@ -9408,7 +9639,7 @@ FreshRSS claims to support HTTP header auth, but at least it does not work with
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
virtualHosts = {
|
virtualHosts = {
|
||||||
"signpost.swarsel.win" = {
|
"${serviceDomain}" = {
|
||||||
enableACME = true;
|
enableACME = true;
|
||||||
forceSSL = true;
|
forceSSL = true;
|
||||||
acmeRoot = null;
|
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;
|
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
|
#+begin_src nix :tangle modules/nixos/server/ankisync.nix
|
||||||
{ lib, config, ... }:
|
{ lib, config, ... }:
|
||||||
|
let
|
||||||
|
serviceDomain = "synki.swarsel.win";
|
||||||
|
in
|
||||||
{
|
{
|
||||||
options.swarselsystems.modules.server.ankisync = lib.mkEnableOption "enable ankisync on server";
|
options.swarselsystems.modules.server.ankisync = lib.mkEnableOption "enable ankisync on server";
|
||||||
config = lib.mkIf config.swarselsystems.modules.server.ankisync {
|
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"; };
|
sops.secrets.swarsel = { owner = "root"; };
|
||||||
|
|
||||||
|
topology.self.services.anki = {
|
||||||
|
name = lib.mkForce "Anki Sync Server";
|
||||||
|
info = "https://${serviceDomain}";
|
||||||
|
};
|
||||||
|
|
||||||
services.anki-sync-server = {
|
services.anki-sync-server = {
|
||||||
enable = true;
|
enable = true;
|
||||||
port = 27701;
|
port = 27701;
|
||||||
|
|
@ -9644,7 +9886,7 @@ FreshRSS claims to support HTTP header auth, but at least it does not work with
|
||||||
|
|
||||||
services.nginx = {
|
services.nginx = {
|
||||||
virtualHosts = {
|
virtualHosts = {
|
||||||
"synki.swarsel.win" = {
|
"${serviceDomain}" = {
|
||||||
enableACME = true;
|
enableACME = true;
|
||||||
forceSSL = true;
|
forceSSL = true;
|
||||||
acmeRoot = null;
|
acmeRoot = null;
|
||||||
|
|
@ -10029,7 +10271,7 @@ To get other URLs (token, etc.), use https://<kanidmDomain>/oauth2/openid/<clien
|
||||||
**** Firefly-III
|
**** Firefly-III
|
||||||
|
|
||||||
#+begin_src nix :tangle modules/nixos/server/firefly-iii.nix
|
#+begin_src nix :tangle modules/nixos/server/firefly-iii.nix
|
||||||
{ lib, config, ... }:
|
{ self, lib, config, ... }:
|
||||||
let
|
let
|
||||||
cfg = config.services.firefly-iii;
|
cfg = config.services.firefly-iii;
|
||||||
fireflyDomain = "stonks.swarsel.win";
|
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 = {
|
services = {
|
||||||
firefly-iii = {
|
firefly-iii = {
|
||||||
enable = true;
|
enable = true;
|
||||||
|
|
@ -10162,7 +10410,7 @@ To get other URLs (token, etc.), use https://<kanidmDomain>/oauth2/openid/<clien
|
||||||
**** Koillection
|
**** Koillection
|
||||||
|
|
||||||
#+begin_src nix :tangle modules/nixos/server/koillection.nix
|
#+begin_src nix :tangle modules/nixos/server/koillection.nix
|
||||||
{ lib, config, ... }:
|
{ self, lib, config, ... }:
|
||||||
let
|
let
|
||||||
serviceDomain = "swag.swarsel.win";
|
serviceDomain = "swag.swarsel.win";
|
||||||
serviceUser = "koillection";
|
serviceUser = "koillection";
|
||||||
|
|
@ -10182,6 +10430,12 @@ To get other URLs (token, etc.), use https://<kanidmDomain>/oauth2/openid/<clien
|
||||||
koillection-env-file = { };
|
koillection-env-file = { };
|
||||||
};
|
};
|
||||||
|
|
||||||
|
topology.self.services.koillection = {
|
||||||
|
name = "Koillection";
|
||||||
|
info = "https://${serviceDomain}";
|
||||||
|
icon = "${self}/topology/images/koillection.png";
|
||||||
|
};
|
||||||
|
|
||||||
virtualisation.oci-containers.containers = {
|
virtualisation.oci-containers.containers = {
|
||||||
koillection = {
|
koillection = {
|
||||||
image = "koillection/koillection@${containerRev}";
|
image = "koillection/koillection@${containerRev}";
|
||||||
|
|
|
||||||
|
|
@ -199,8 +199,7 @@
|
||||||
lib.swarselsystems.forEachSystem (pkgs: import inputs.nix-topology {
|
lib.swarselsystems.forEachSystem (pkgs: import inputs.nix-topology {
|
||||||
inherit pkgs;
|
inherit pkgs;
|
||||||
modules = [
|
modules = [
|
||||||
# Your own file to define global topology. Works in principle like a nixos module but uses different options.
|
"${self}/topology"
|
||||||
# ./topology.nix
|
|
||||||
{ inherit (self) nixosConfigurations; }
|
{ inherit (self) nixosConfigurations; }
|
||||||
];
|
];
|
||||||
});
|
});
|
||||||
|
|
|
||||||
|
|
@ -45,9 +45,9 @@ in
|
||||||
firewall.enable = true;
|
firewall.enable = true;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
swarselsystems = lib.recursiveUpdate
|
swarselsystems = lib.recursiveUpdate
|
||||||
{
|
{
|
||||||
|
info = "~SwarselSystems~ demo host";
|
||||||
wallpaper = self + /wallpaper/lenovowp.png;
|
wallpaper = self + /wallpaper/lenovowp.png;
|
||||||
initialSetup = true;
|
initialSetup = true;
|
||||||
isImpermanence = true;
|
isImpermanence = true;
|
||||||
|
|
|
||||||
|
|
@ -10,6 +10,7 @@ in
|
||||||
|
|
||||||
"${self}/modules/iso/minimal.nix"
|
"${self}/modules/iso/minimal.nix"
|
||||||
"${self}/modules/nixos/common/sharedsetup.nix"
|
"${self}/modules/nixos/common/sharedsetup.nix"
|
||||||
|
"${self}/modules/nixos/common/topology.nix"
|
||||||
"${self}/modules/home/common/sharedsetup.nix"
|
"${self}/modules/home/common/sharedsetup.nix"
|
||||||
|
|
||||||
inputs.home-manager.nixosModules.home-manager
|
inputs.home-manager.nixosModules.home-manager
|
||||||
|
|
@ -33,7 +34,10 @@ in
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
config = {
|
config = {
|
||||||
node.name = "drugstore";
|
node.name = lib.mkForce "drugstore";
|
||||||
|
swarselsystems = {
|
||||||
|
info = "~SwarselSystems~ installer ISO";
|
||||||
|
};
|
||||||
home-manager.users."${primaryUser}" = {
|
home-manager.users."${primaryUser}" = {
|
||||||
home = {
|
home = {
|
||||||
stateVersion = "23.05";
|
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 = {
|
home-manager.users.root.home = {
|
||||||
stateVersion = "23.05";
|
stateVersion = "23.05";
|
||||||
|
|
|
||||||
|
|
@ -39,6 +39,12 @@ in
|
||||||
];
|
];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
topology.self.interfaces.wg = {
|
||||||
|
addresses = [ "192.168.3.4" ];
|
||||||
|
renderer.hidePhysicalConnections = true;
|
||||||
|
virtual = true;
|
||||||
|
type = "wireguard";
|
||||||
|
};
|
||||||
|
|
||||||
networking = {
|
networking = {
|
||||||
nftables.enable = lib.mkForce false;
|
nftables.enable = lib.mkForce false;
|
||||||
|
|
@ -80,26 +86,13 @@ in
|
||||||
services = {
|
services = {
|
||||||
nginx = {
|
nginx = {
|
||||||
virtualHosts = {
|
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" = {
|
"syncthing.swarsel.win" = {
|
||||||
enableACME = true;
|
enableACME = true;
|
||||||
forceSSL = true;
|
forceSSL = true;
|
||||||
acmeRoot = null;
|
acmeRoot = null;
|
||||||
locations = {
|
locations = {
|
||||||
"/" = {
|
"/" = {
|
||||||
proxyPass = "http://localhost:8384/";
|
proxyPass = "http://localhost:8384";
|
||||||
extraConfig = ''
|
extraConfig = ''
|
||||||
client_max_body_size 0;
|
client_max_body_size 0;
|
||||||
'';
|
'';
|
||||||
|
|
@ -221,6 +214,7 @@ in
|
||||||
|
|
||||||
swarselsystems = lib.recursiveUpdate
|
swarselsystems = lib.recursiveUpdate
|
||||||
{
|
{
|
||||||
|
info = "VM.Standard.A1.Flex, 4 OCPUs, 24GB RAM";
|
||||||
flakePath = "/home/swarsel/.dotfiles";
|
flakePath = "/home/swarsel/.dotfiles";
|
||||||
isImpermanence = true;
|
isImpermanence = true;
|
||||||
isSecureBoot = false;
|
isSecureBoot = false;
|
||||||
|
|
|
||||||
|
|
@ -24,6 +24,7 @@ in
|
||||||
|
|
||||||
swarselsystems = lib.recursiveUpdate
|
swarselsystems = lib.recursiveUpdate
|
||||||
{
|
{
|
||||||
|
info = "Framework Laptop 16, 7940HS, RX7700S, 64GB RAM";
|
||||||
firewall = lib.mkForce true;
|
firewall = lib.mkForce true;
|
||||||
wallpaper = self + /wallpaper/lenovowp.png;
|
wallpaper = self + /wallpaper/lenovowp.png;
|
||||||
hasBluetooth = true;
|
hasBluetooth = true;
|
||||||
|
|
|
||||||
|
|
@ -60,7 +60,7 @@ in
|
||||||
acmeRoot = null;
|
acmeRoot = null;
|
||||||
locations = {
|
locations = {
|
||||||
"/" = {
|
"/" = {
|
||||||
proxyPass = "http://localhost:8384/";
|
proxyPass = "http://localhost:8384";
|
||||||
extraConfig = ''
|
extraConfig = ''
|
||||||
client_max_body_size 0;
|
client_max_body_size 0;
|
||||||
'';
|
'';
|
||||||
|
|
@ -152,6 +152,7 @@ in
|
||||||
|
|
||||||
swarselsystems = lib.recursiveUpdate
|
swarselsystems = lib.recursiveUpdate
|
||||||
{
|
{
|
||||||
|
info = "VM.Standard.E2.1.Micro";
|
||||||
flakePath = "/root/.dotfiles";
|
flakePath = "/root/.dotfiles";
|
||||||
isImpermanence = false;
|
isImpermanence = false;
|
||||||
isSecureBoot = false;
|
isSecureBoot = false;
|
||||||
|
|
|
||||||
|
|
@ -57,6 +57,7 @@ in
|
||||||
|
|
||||||
swarselsystems = lib.recursiveUpdate
|
swarselsystems = lib.recursiveUpdate
|
||||||
{
|
{
|
||||||
|
info = "~SwarselSystems~ remote install helper";
|
||||||
wallpaper = self + /wallpaper/lenovowp.png;
|
wallpaper = self + /wallpaper/lenovowp.png;
|
||||||
isImpermanence = true;
|
isImpermanence = true;
|
||||||
isCrypted = false;
|
isCrypted = false;
|
||||||
|
|
|
||||||
|
|
@ -30,6 +30,7 @@ in
|
||||||
|
|
||||||
swarselsystems = lib.recursiveUpdate
|
swarselsystems = lib.recursiveUpdate
|
||||||
{
|
{
|
||||||
|
info = "ASRock J4105-ITX, 32GB RAM";
|
||||||
isImpermanence = false;
|
isImpermanence = false;
|
||||||
isSecureBoot = true;
|
isSecureBoot = true;
|
||||||
isCrypted = true;
|
isCrypted = true;
|
||||||
|
|
|
||||||
2453
index.html
|
|
@ -22,6 +22,7 @@ in
|
||||||
pkgsFor = lib.genAttrs (import systems) (system:
|
pkgsFor = lib.genAttrs (import systems) (system:
|
||||||
import inputs.nixpkgs {
|
import inputs.nixpkgs {
|
||||||
inherit system;
|
inherit system;
|
||||||
|
overlays = [ self.overlays.default ];
|
||||||
config.allowUnfree = true;
|
config.allowUnfree = true;
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
@ -69,43 +70,45 @@ in
|
||||||
_module.args.primaryUser = linuxUser;
|
_module.args.primaryUser = linuxUser;
|
||||||
}
|
}
|
||||||
] ++
|
] ++
|
||||||
(if (host == "iso") then [ ] else
|
(if (host == "iso") then [
|
||||||
([
|
|
||||||
# put nixos imports here that are for all servers and normal hosts
|
|
||||||
inputs.nix-topology.nixosModules.default
|
inputs.nix-topology.nixosModules.default
|
||||||
"${self}/modules/${type}/common"
|
] else
|
||||||
inputs.stylix.nixosModules.stylix
|
([
|
||||||
inputs.nswitch-rcm-nix.nixosModules.nswitch-rcm
|
# put nixos imports here that are for all servers and normal hosts
|
||||||
] ++ (if (type == "nixos") then [
|
inputs.nix-topology.nixosModules.default
|
||||||
inputs.home-manager.nixosModules.home-manager
|
"${self}/modules/${type}/common"
|
||||||
"${self}/profiles/nixos"
|
inputs.stylix.nixosModules.stylix
|
||||||
"${self}/modules/nixos/server"
|
inputs.nswitch-rcm-nix.nixosModules.nswitch-rcm
|
||||||
"${self}/modules/nixos/optional"
|
] ++ (if (type == "nixos") then [
|
||||||
{
|
inputs.home-manager.nixosModules.home-manager
|
||||||
home-manager.users."${linuxUser}".imports = [
|
"${self}/profiles/nixos"
|
||||||
# put home-manager imports here that are for all normal hosts
|
"${self}/modules/nixos/server"
|
||||||
"${self}/modules/home/common"
|
"${self}/modules/nixos/optional"
|
||||||
"${self}/modules/home/server"
|
{
|
||||||
"${self}/modules/home/optional"
|
home-manager.users."${linuxUser}".imports = [
|
||||||
"${self}/profiles/home"
|
# put home-manager imports here that are for all normal hosts
|
||||||
];
|
"${self}/modules/home/common"
|
||||||
}
|
"${self}/modules/home/server"
|
||||||
] else [
|
"${self}/modules/home/optional"
|
||||||
# put nixos imports here that are for darwin hosts
|
"${self}/profiles/home"
|
||||||
"${self}/modules/darwin/nixos/common"
|
];
|
||||||
"${self}/profiles/darwin"
|
}
|
||||||
inputs.home-manager.darwinModules.home-manager
|
] else [
|
||||||
{
|
# put nixos imports here that are for darwin hosts
|
||||||
home-manager.users."${macUser}".imports = [
|
"${self}/modules/darwin/nixos/common"
|
||||||
# put home-manager imports here that are for darwin hosts
|
"${self}/profiles/darwin"
|
||||||
"${self}/modules/darwin/home"
|
inputs.home-manager.darwinModules.home-manager
|
||||||
"${self}/modules/home/server"
|
{
|
||||||
"${self}/modules/home/optional"
|
home-manager.users."${macUser}".imports = [
|
||||||
"${self}/profiles/home"
|
# put home-manager imports here that are for darwin hosts
|
||||||
];
|
"${self}/modules/darwin/home"
|
||||||
}
|
"${self}/modules/home/server"
|
||||||
])
|
"${self}/modules/home/optional"
|
||||||
));
|
"${self}/profiles/home"
|
||||||
|
];
|
||||||
|
}
|
||||||
|
])
|
||||||
|
));
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,12 +1,16 @@
|
||||||
{ lib, ... }:
|
{ lib, ... }:
|
||||||
{
|
{
|
||||||
options.node.secretsDir = lib.mkOption {
|
options = {
|
||||||
description = "Path to the secrets directory for this node.";
|
node = {
|
||||||
type = lib.types.path;
|
secretsDir = lib.mkOption {
|
||||||
default = ./.;
|
description = "Path to the secrets directory for this node.";
|
||||||
};
|
type = lib.types.path;
|
||||||
options.node.name = lib.mkOption {
|
default = ./.;
|
||||||
description = "Node Name.";
|
};
|
||||||
type = lib.types.str;
|
name = lib.mkOption {
|
||||||
|
description = "Node Name.";
|
||||||
|
type = lib.types.str;
|
||||||
|
};
|
||||||
|
};
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -72,6 +72,8 @@
|
||||||
zls
|
zls
|
||||||
ansible-language-server
|
ansible-language-server
|
||||||
|
|
||||||
|
elk-to-svg
|
||||||
|
|
||||||
];
|
];
|
||||||
|
|
||||||
nixpkgs.config.permittedInsecurePackages = [
|
nixpkgs.config.permittedInsecurePackages = [
|
||||||
|
|
|
||||||
14
modules/nixos/common/topology.nix
Normal 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";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
@ -1,4 +1,7 @@
|
||||||
{ lib, config, ... }:
|
{ lib, config, ... }:
|
||||||
|
let
|
||||||
|
serviceDomain = "synki.swarsel.win";
|
||||||
|
in
|
||||||
{
|
{
|
||||||
options.swarselsystems.modules.server.ankisync = lib.mkEnableOption "enable ankisync on server";
|
options.swarselsystems.modules.server.ankisync = lib.mkEnableOption "enable ankisync on server";
|
||||||
config = lib.mkIf config.swarselsystems.modules.server.ankisync {
|
config = lib.mkIf config.swarselsystems.modules.server.ankisync {
|
||||||
|
|
@ -7,6 +10,11 @@
|
||||||
|
|
||||||
sops.secrets.swarsel = { owner = "root"; };
|
sops.secrets.swarsel = { owner = "root"; };
|
||||||
|
|
||||||
|
topology.self.services.anki = {
|
||||||
|
name = lib.mkForce "Anki Sync Server";
|
||||||
|
info = "https://${serviceDomain}";
|
||||||
|
};
|
||||||
|
|
||||||
services.anki-sync-server = {
|
services.anki-sync-server = {
|
||||||
enable = true;
|
enable = true;
|
||||||
port = 27701;
|
port = 27701;
|
||||||
|
|
@ -22,7 +30,7 @@
|
||||||
|
|
||||||
services.nginx = {
|
services.nginx = {
|
||||||
virtualHosts = {
|
virtualHosts = {
|
||||||
"synki.swarsel.win" = {
|
"${serviceDomain}" = {
|
||||||
enableACME = true;
|
enableACME = true;
|
||||||
forceSSL = true;
|
forceSSL = true;
|
||||||
acmeRoot = null;
|
acmeRoot = null;
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
{ lib, config, ... }:
|
{ self, lib, config, ... }:
|
||||||
let
|
let
|
||||||
cfg = config.services.firefly-iii;
|
cfg = config.services.firefly-iii;
|
||||||
fireflyDomain = "stonks.swarsel.win";
|
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 = {
|
services = {
|
||||||
firefly-iii = {
|
firefly-iii = {
|
||||||
enable = true;
|
enable = true;
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,7 @@
|
||||||
{ lib, config, ... }:
|
{ self, lib, config, ... }:
|
||||||
let
|
let
|
||||||
serviceName = "freshrss";
|
serviceName = "freshrss";
|
||||||
|
serviceDomain = "signpost.swarsel.win";
|
||||||
in
|
in
|
||||||
{
|
{
|
||||||
options.swarselsystems.modules.server.freshrss = lib.mkEnableOption "enable freshrss on server";
|
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 = {
|
services.freshrss = {
|
||||||
enable = true;
|
enable = true;
|
||||||
virtualHost = "signpost.swarsel.win";
|
virtualHost = serviceDomain;
|
||||||
baseUrl = "https://signpost.swarsel.win";
|
baseUrl = "https://${serviceDomain}";
|
||||||
authType = "form";
|
authType = "form";
|
||||||
dataDir = "/Vault/data/tt-rss";
|
dataDir = "/Vault/data/tt-rss";
|
||||||
defaultUser = "Swarsel";
|
defaultUser = "Swarsel";
|
||||||
|
|
@ -64,7 +71,7 @@ in
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
virtualHosts = {
|
virtualHosts = {
|
||||||
"signpost.swarsel.win" = {
|
"${serviceDomain}" = {
|
||||||
enableACME = true;
|
enableACME = true;
|
||||||
forceSSL = true;
|
forceSSL = true;
|
||||||
acmeRoot = null;
|
acmeRoot = null;
|
||||||
|
|
@ -110,6 +117,9 @@ in
|
||||||
proxy_pass_request_body off;
|
proxy_pass_request_body off;
|
||||||
'';
|
'';
|
||||||
};
|
};
|
||||||
|
"/api" = {
|
||||||
|
proxyPass = "http://${serviceName}";
|
||||||
|
};
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -13,6 +13,8 @@ in
|
||||||
extraGroups = [ "video" "render" "users" ];
|
extraGroups = [ "video" "render" "users" ];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
topology.self.services.immich.info = "https://${serviceDomain}";
|
||||||
|
|
||||||
services.immich = {
|
services.immich = {
|
||||||
enable = true;
|
enable = true;
|
||||||
host = "0.0.0.0";
|
host = "0.0.0.0";
|
||||||
|
|
|
||||||
|
|
@ -23,6 +23,9 @@ in
|
||||||
libvdpau-va-gl
|
libvdpau-va-gl
|
||||||
];
|
];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
topology.self.services.jellyfin.info = "https://${serviceDomain}";
|
||||||
|
|
||||||
services.jellyfin = {
|
services.jellyfin = {
|
||||||
enable = true;
|
enable = true;
|
||||||
user = serviceUser;
|
user = serviceUser;
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
{ pkgs, lib, config, ... }:
|
{ self, lib, config, pkgs, ... }:
|
||||||
let
|
let
|
||||||
serviceName = "kavita";
|
serviceName = "kavita";
|
||||||
serviceUser = "kavita";
|
serviceUser = "kavita";
|
||||||
|
|
@ -20,6 +20,12 @@ in
|
||||||
|
|
||||||
networking.firewall.allowedTCPPorts = [ 8080 ];
|
networking.firewall.allowedTCPPorts = [ 8080 ];
|
||||||
|
|
||||||
|
topology.self.services.kavita = {
|
||||||
|
name = "Kavita";
|
||||||
|
info = "https://${serviceDomain}";
|
||||||
|
icon = "${self}/topology/images/kavita.png";
|
||||||
|
};
|
||||||
|
|
||||||
services.kavita = {
|
services.kavita = {
|
||||||
enable = true;
|
enable = true;
|
||||||
user = serviceUser;
|
user = serviceUser;
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
{ lib, config, ... }:
|
{ self, lib, config, ... }:
|
||||||
let
|
let
|
||||||
serviceDomain = "swag.swarsel.win";
|
serviceDomain = "swag.swarsel.win";
|
||||||
serviceUser = "koillection";
|
serviceUser = "koillection";
|
||||||
|
|
@ -18,6 +18,12 @@ in
|
||||||
koillection-env-file = { };
|
koillection-env-file = { };
|
||||||
};
|
};
|
||||||
|
|
||||||
|
topology.self.services.koillection = {
|
||||||
|
name = "Koillection";
|
||||||
|
info = "https://${serviceDomain}";
|
||||||
|
icon = "${self}/topology/images/koillection.png";
|
||||||
|
};
|
||||||
|
|
||||||
virtualisation.oci-containers.containers = {
|
virtualisation.oci-containers.containers = {
|
||||||
koillection = {
|
koillection = {
|
||||||
image = "koillection/koillection@${containerRev}";
|
image = "koillection/koillection@${containerRev}";
|
||||||
|
|
|
||||||
|
|
@ -34,6 +34,8 @@ in
|
||||||
|
|
||||||
networking.firewall.allowedTCPPorts = [ servicePort prometheusPort ];
|
networking.firewall.allowedTCPPorts = [ servicePort prometheusPort ];
|
||||||
|
|
||||||
|
topology.self.services.prometheus.info = "https://${serviceDomain}/${prometheusWebRoot}";
|
||||||
|
|
||||||
services = {
|
services = {
|
||||||
grafana = {
|
grafana = {
|
||||||
enable = true;
|
enable = true;
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
{ pkgs, lib, config, ... }:
|
{ self, lib, config, pkgs, ... }:
|
||||||
{
|
{
|
||||||
options.swarselsystems.modules.server.mpd = lib.mkEnableOption "enable mpd on server";
|
options.swarselsystems.modules.server.mpd = lib.mkEnableOption "enable mpd on server";
|
||||||
config = lib.mkIf config.swarselsystems.modules.server.mpd {
|
config = lib.mkIf config.swarselsystems.modules.server.mpd {
|
||||||
|
|
@ -26,6 +26,12 @@
|
||||||
mpv
|
mpv
|
||||||
];
|
];
|
||||||
|
|
||||||
|
topology.self.services.mpd = {
|
||||||
|
name = "MPD";
|
||||||
|
info = "http://localhost:3254";
|
||||||
|
icon = "${self}/topology/images/mpd.png";
|
||||||
|
};
|
||||||
|
|
||||||
services.mpd = {
|
services.mpd = {
|
||||||
enable = true;
|
enable = true;
|
||||||
musicDirectory = "/media";
|
musicDirectory = "/media";
|
||||||
|
|
|
||||||
|
|
@ -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";
|
options.swarselsystems.modules.server.transmission = lib.mkEnableOption "enable transmission and friends on server";
|
||||||
config = lib.mkIf config.swarselsystems.modules.server.transmission {
|
config = lib.mkIf config.swarselsystems.modules.server.transmission {
|
||||||
|
|
@ -55,6 +58,18 @@
|
||||||
docker
|
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 = {
|
services = {
|
||||||
radarr = {
|
radarr = {
|
||||||
enable = true;
|
enable = true;
|
||||||
|
|
|
||||||
154
topology/default.nix
Normal 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 = { };
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
||||||
BIN
topology/images/DELL-C2665dnf.png
Normal file
|
After Width: | Height: | Size: 122 KiB |
BIN
topology/images/TL-SG1005D.png
Normal file
|
After Width: | Height: | Size: 393 KiB |
BIN
topology/images/TL-SG108.png
Normal file
|
After Width: | Height: | Size: 139 KiB |
BIN
topology/images/firefly-iii.png
Normal file
|
After Width: | Height: | Size: 90 KiB |
BIN
topology/images/freshrss.png
Normal file
|
After Width: | Height: | Size: 14 KiB |
BIN
topology/images/huawei.png
Normal file
|
After Width: | Height: | Size: 157 KiB |
BIN
topology/images/hunsn.png
Normal file
|
After Width: | Height: | Size: 205 KiB |
BIN
topology/images/kavita.png
Normal file
|
After Width: | Height: | Size: 1.9 KiB |
BIN
topology/images/koillection.png
Normal file
|
After Width: | Height: | Size: 23 KiB |
BIN
topology/images/mpd.png
Normal file
|
After Width: | Height: | Size: 9.7 KiB |
BIN
topology/images/nintendo-switch.png
Normal file
|
After Width: | Height: | Size: 84 KiB |
BIN
topology/images/pc.png
Normal file
|
After Width: | Height: | Size: 107 KiB |
BIN
topology/images/readarr.png
Normal file
|
After Width: | Height: | Size: 18 KiB |