chore: clean up flake

This commit is contained in:
Leon Schwarzäugl 2025-07-02 01:16:42 +02:00
parent 178d51cde6
commit 6ca7717d3e
Signed by: swarsel
GPG key ID: 26A54C31F2A4FD84
63 changed files with 5134 additions and 1157 deletions

File diff suppressed because it is too large Load diff

View file

@ -2,6 +2,8 @@
let
inherit (config.repo.secrets.common) workHostName;
inherit (config.repo.secrets.local.syncthing) dev1 dev2 dev3 loc1;
serviceDomain = config.repo.secrets.common.services.domains.syncthing3;
sharedOptions = {
isBtrfs = true;
isLinux = true;
@ -83,10 +85,12 @@ in
system.stateVersion = "23.11";
globals.services."syncthing-${config.networking.hostName}".domain = serviceDomain;
services = {
nginx = {
virtualHosts = {
"syncthing.swarsel.win" = {
${serviceDomain} = {
enableACME = true;
forceSSL = true;
acmeRoot = null;

View file

@ -6,6 +6,7 @@ let
};
inherit (config.repo.secrets.common) workHostName;
inherit (config.repo.secrets.local.syncthing) dev1 dev2 dev3 loc1;
serviceDomain = config.repo.secrets.common.services.domains.syncthing2;
in
{
imports = [
@ -50,11 +51,12 @@ in
system.stateVersion = "23.11";
globals.services."syncthing-${config.networking.hostName}".domain = serviceDomain;
services = {
nginx = {
virtualHosts = {
"sync.swarsel.win" = {
${serviceDomain} = {
enableACME = true;
forceSSL = true;
acmeRoot = null;

View file

@ -1,8 +1,4 @@
{ config
, lib
, modulesPath
, ...
}: {
{ config, lib, modulesPath, ... }: {
imports = [
(modulesPath + "/profiles/qemu-guest.nix")
];

View file

@ -1,5 +1,5 @@
{
"data": "ENC[AES256_GCM,data:Bb45EoiwDMRxYR/YAmYcwn7HT3mF0kT1DHmBclmCxj0xK81qqQzFZyF+2WKFwyMYAC0gfOpeoi9B+a2nNfIaY7hujqQ1luLOaHAL687hKFM1w62U1w5XNs9Rs0OnO99ag8IZTAjY0lqC4djTrTlklx+x6qzISW2z191SMho4zD89mKA2qCk3iYd37+N/uOZ4LSPSBtX625d2lXZPpWhBDd/UrlZqwQqGa+cxdeM3QcRr+Xnv4hYVg+UC2kGXwBWCkMY9S12iQp0CQTMAcqhgfs5J7tdxycYcXYJZjUGfJBTrG6t5xVzzibKFpAjpl9aqiUGLNHf1EtwBP4+PtEs7XQCHltsz8PA4PtH291RVzT4FYUbkCTw1gQBgB1tQzwa4Gc7MBtvAR4DCXrTfda5eYGUzwBsCC9AVNI1jEaDncaiPPjK8rzyjcZGK9i5hMDf5L0XqLKG350RPRWMPFCnCml67n+tnEp4JsOfadpIJ7iCrBTXpgWHVXBcOKuEjIjAInBtzOUrV1AbH6f45R6N1jOoe315t4FlWPL4M0oUemi6Uw8NYiX80X2VD558j80jLZVfybz87IlvTI/GiI1GykkRoanH2LURtrzLUAGtpvK8ueCeKStYDLt89s4m8HFO/p8hhQ1id6vD8VAyvp7n6lZ4SUOjyWy1DTsR9YMz/t7oilwfsfp7bSiFzqk3cOgbZsdbyZZVNlGdN4XeWUHIztpiy1239N70xeE7HeJODkgrVs6HI8GME1LDtYZcBzyh1zHIInT5gv4fNBDTCG4a3yhpuDIPnCXwC3L93wX058u2t0ETcaeMRjeWZU0H0PFfM9DhjO6wmWRxQ0yqT69b1gsCoUWdsixfUtJQ9dKstM5pdJCNiEvehMC5SPXP20PPeZEIlmVnXGQqAs6Bcpo+TmdrNaI7llHPmRVE9MeumqC7V22eHVpwawP4NHwLXtL/SjZuMWDc7F2DnCm3lHxxqVfWS6XFFB+WcBkmQFh2cqCuRsGhXFUPevxpDp0thL8rBnUzro/Xlh1KvBSstC75m1c4dx/EL7yBLWllWOVCEQU7R2QEw77G/viCx3/KCuJrkTWXOyiREqXdUDin2N4jZAhH3QKONrBYYBubVPIpaWZEindKyjNdItFxTbSDb5MwOtBsCNhLTqT45vefXh4LYYOf/+YvUmEw9nkgQn5Nw8vJ8H2mpLyLGgKupSYdlErmcu59QWwjW3drentzx8DhMWBiICkAWRe8PHXZHcC8kD0+sEXtBtvtfgkQ3aYv2aF0Dy3DHcHhf2auDCuJr6IBwwM2RKO4EhS2Ec9YKVyDXC7/bZqsymTyCawKCQZYCK9ZPcI97gTM=,iv:peWndkV5HrPgsJTgMvDM+uLO6jqfpIBiiQzL80dqCFM=,tag:gPkHLiO6/yPUIZ6q/X4Thg==,type:str]",
"data": "ENC[AES256_GCM,data:XEzKhJ1+iwQZ24wnf7FdThWMwOKEwaYr3ecGjjLpTqx4+kq3W9FWFDSKkHAwo6077tsVTu7NCGZfat/gAylg1xgqAZAHA8/PMQejowAgIPCG7eCQvQfTMepcuWjgc9BAyFYcBjPFmLnvX69LE80Fw0Io1QeKIa6CVJKp4P6eC8OIKeG1fTc3/sWxr+3ZKTzGPKiGCnSMo7qM0/2HlV0bhp8yWFni+2nZ8UlPJluEnmx0bBR0uZ6bdqzLX/fFrmgTd6m30+Zq8pjKVhiHpEQd9m5aU2inCWv4OeNE3EQsLYcnhcVdrcySZ6R4AZ1nlZZedDhf+Ee4AwcIPVsA8HHqlUEY1CayHF5wLpkxralOpt+RFZYJkvupmozP/uYRymoAA6YgJGesr2Oki0wT041nioB9AvpU9xFvfCqbqXXsBvwtvhxpwhEJJOogZENKnjvvoDoLGZlFVPzkfqDANuv5SAJQiWuFLWEdcmQncRlsjwSPOGOnI+r+puHszPOaDsZigF/yuL4rd5a0RkS6dCOfYtCvQBBAMfEAWX13AiKF0Dtz5/ijEEK7iojoMF/B6rnoENs2l0cSljq7TGV0DVRDjFUTiMNbfRxUJUkMuqJFnNzMwz4METmAwgqHn217uvUk2V8UJ5v9k4sapRmogPTfCwhvxGDV1e9AJvL6WXJ2m0ldhKOcQXFiO/+ZtNB1FHJ22ZFcxcSSOSRmEQsB5Yw3zPEjQ7sU93sKRLEPrTEqSSNG75iZ+vZm9iEI2trFhtEOlU98Ury/USC9sjPN/sxGGR5hcRZajY2HUxVTucMheIWJ7mxhxLHg7rz/qWLSqC6TqKwnyv+NdBnrVaLWaRnZGRCgtvN+oJKRjyxCsiDHVoY52cP5SmdXGn3yrVxDuYGrkLf/JOj76Hs/TCSsYptMvKqH4R4vT8SlDnplpcIfd5KTr4sM1n4q4sai1wRc1wlN0EkwK7+otTYcStxtvgUUtW/4jkk+73TdvvR9IkV0PqghKuB6FdAM6qRX1M8AebcXNyZYW9k7sHRVWGk+eMrMe/qX2IAY1WUgdt7hs2Ci9XoJqWKCG17rcKZ/ORu0utrJt+l0H9fZihO8+aYHabsHueiyJTKJvZx9+12r5a6deXShtdpsdQVnMlczWKGKUIdQ7TB12HILGPAvvZkJh0aDq043UU/4dUwyUezi70QnH/Z/GRip68kXH6njBmZRlmmNAFSCHkGxMKxpgssHyXXNEvET/TIVEJeR1vYjqFoGIBrFQV1Bqu2yk3A2pZLBEEbsCQrOuE2CPpfrn5kCUnw2sJOWpnVqyQ+SA4xZ7W1vw7i8aL2ThZlKE3zsriECpOfEaDWv8ME2HsiL42VUmgv+6zm/2hiVK+OayQucBUbY8IC6Yjl2kXB7EPvUsc60V2xOJl40KIAJxa0GNgaRMWkYoFtnVrYbY4yT37UjIAu2fJD725qgkXOJwbFPlX7na86PVVB0MQ==,iv:JSG8DynJg8t7HEDoW7IwYt189P22h4BPMFYsJmo3mcU=,tag:cHoNQBL2DCpntJyhqay54Q==,type:str]",
"sops": {
"age": [
{
@ -7,8 +7,8 @@
"enc": "-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSAyK0w2RjJ5R1l2ay94QXRj\nekJwSlowcFVLc1cvWVFjNEVFUnFocEJHYlNnCnBnUEYvNWdNWE9BTjB5ODRuTlAw\nMUh4QmlTeVVYNHM0S1FwWG5qUG42VDgKLS0tIHh5VlU2dVZmUlRIMDRlVEJmNU55\ncFlXR1BzMkVnMkFWN3BBZWhHalltMlEKibdARxBcFqaXUhYp3KkrrvO9YgaBDacl\n8BEv4ph0f2baDN0dsymJjmdHStwKTjOwDspRtCTs5u75hR35a2xyFQ==\n-----END AGE ENCRYPTED FILE-----\n"
}
],
"lastmodified": "2025-06-28T22:52:43Z",
"mac": "ENC[AES256_GCM,data:iv7/BhKzDCsx3I7lmwaBr9BHvTausvWDky2drGZD0YXJqh3KNAp9e2MZnPs8RzsavsEd23JG6Xi1u9cnlcJtmkebBTqrUPZOSJz6RTw/YAlCSR+d1Az5B10jY1wVeweGDVUn0ncVx2zzEjbguMQz4T1kcZU5XT7MX8XITDE6J9M=,iv:xPNHn6E4oTQ7F5f9Df8M+G07uxhhW7mXh2BWUX5cD9M=,tag:cU2OFctCdqdgQnTKns0yOQ==,type:str]",
"lastmodified": "2025-07-02T10:26:33Z",
"mac": "ENC[AES256_GCM,data:/rmQKH7up3IcAdyYpdpx6H6gdyiNsnPS6TaozSU0EXxoaods50xC5sf2/quqLaeSRJE/NjKvh+3BWchbFJMQZM4PvSML3XAO8w9t/GqmOwwLJrvnMyulqS5y7BVDJZysmDe9TFNz05UJfZdbvLrH8kyhTHF7ciA8HgJq5JzFiBc=,iv:ORyza5fzjptuq5WD3NA9/OTFbACtzHp5e6kNKT/EaTE=,tag:wsp3Z/ySHVmDC9uRCn30Uw==,type:str]",
"pgp": [
{
"created_at": "2025-06-11T11:42:23Z",

2603
index.html

File diff suppressed because it is too large Load diff

View file

@ -1,4 +1,7 @@
{ lib, config, ... }:
{ lib, config, globals, ... }:
let
atuinDomain = globals.services.atuin.domain;
in
{
options.swarselsystems.modules.atuin = lib.mkEnableOption "atuin settings";
config = lib.mkIf config.swarselsystems.modules.atuin {
@ -8,7 +11,7 @@
settings = {
auto_sync = true;
sync_frequency = "5m";
sync_address = "https://shellhistory.swarsel.win";
sync_address = "https://${atuinDomain}";
};
};
};

View file

@ -1,7 +1,8 @@
{ lib, config, nixosConfig, ... }:
{ lib, config, nixosConfig, globals, ... }:
let
inherit (nixosConfig.repo.secrets.common.mail) address1 address2 address3 address4 allMailAddresses;
inherit (nixosConfig.repo.secrets.common) fullName;
crocDomain = globals.services.croc.domain;
in
{
options.swarselsystems.modules.env = lib.mkEnableOption "env settings";
@ -9,11 +10,11 @@ in
home.sessionVariables = {
EDITOR = "e -w";
DISPLAY = ":0";
CROC_RELAY = "send.swarsel.win";
CROC_RELAY = crocDomain;
SWARSEL_LO_RES = config.swarselsystems.lowResolution;
SWARSEL_HI_RES = config.swarselsystems.highResolution;
};
systemd.user.sessionVariables = {
systemd.user.sessionVariables = lib.mkIf (config.swarselsystems.isNixos && !config.swarselsystems.isPublic) {
SWARSEL_MAIL1 = address1;
SWARSEL_MAIL2 = address2;
SWARSEL_MAIL3 = address3;

View file

@ -5,7 +5,7 @@ in
{
options.swarselsystems.modules.gammastep = lib.mkEnableOption "gammastep settings";
config = lib.mkIf config.swarselsystems.modules.gammastep {
services.gammastep = {
services.gammastep = lib.mkIf (config.swarselsystems.isNixos && !config.swarselsystems.isPublic) {
enable = true;
provider = "manual";
inherit longitude latitude;

View file

@ -1,7 +1,9 @@
{ lib, config, nixosConfig, ... }:
{ lib, config, nixosConfig, globals, ... }:
let
inherit (nixosConfig.repo.secrets.common.mail) address1;
inherit (nixosConfig.repo.secrets.common) fullName;
gitUser = globals.user.name;
in
{
options.swarselsystems.modules.git = lib.mkEnableOption "git settings";
@ -25,15 +27,15 @@ in
key = "0x76FD3810215AE097";
signByDefault = true;
};
userEmail = lib.mkDefault address1;
userName = fullName;
userEmail = lib.mkIf (config.swarselsystems.isNixos && !config.swarselsystems.isPublic) (lib.mkDefault address1);
userName = lib.mkIf (config.swarselsystems.isNixos && !config.swarselsystems.isPublic) fullName;
difftastic.enable = true;
lfs.enable = true;
includes = [
{
contents = {
github = {
user = "Swarsel";
user = gitUser;
};
commit = {
template = "~/.gitmessage";

View file

@ -24,7 +24,7 @@ in
# this is needed so that mbsync can use the passwords from sops
systemd.user.services.mbsync.Unit.After = [ "sops-nix.service" ];
accounts = lib.mkIf (!config.swarselsystems.isPublic) {
accounts = lib.mkIf (config.swarselsystems.isNixos && !config.swarselsystems.isPublic) {
email = {
maildirBasePath = "Mail";
accounts = {

View file

@ -79,7 +79,7 @@
obsidian
spotify
vesktop # discord client
nextcloud-client
# nextcloud-client # enables a systemd service that I do not want
spotify-player
element-desktop
nicotine-plus

View file

@ -1,4 +1,4 @@
{ self, config, lib, ... }:
{ self, config, lib, pkgs, ... }:
let
generateIcons = n: lib.concatStringsSep " " (builtins.map (x: "{icon" + toString x + "}") (lib.range 0 (n - 1)));
modulesLeft = [
@ -79,28 +79,28 @@ in
"custom/pseudobat" = lib.mkIf (!config.swarselsystems.isLaptop) {
format = "";
on-click-right = "wlogout -p layer-shell";
on-click-right = "${pkgs.wlogout}/bin/wlogout -p layer-shell";
};
"custom/configwarn" = {
exec = "waybarupdate";
exec = "${pkgs.waybarupdate}/bin/waybarupdate";
interval = 60;
};
"custom/scratchpad-indicator" = {
interval = 3;
exec = "swaymsg -t get_tree | jq 'recurse(.nodes[]) | first(select(.name==\"__i3_scratch\")) | .floating_nodes | length | select(. >= 1)'";
exec = "${pkgs.swayfx}/bin/swaymsg -t get_tree | ${pkgs.jq}/bin/jq 'recurse(.nodes[]) | first(select(.name==\"__i3_scratch\")) | .floating_nodes | length | select(. >= 1)'";
format = "{} ";
on-click = "swaymsg 'scratchpad show'";
on-click-right = "swaymsg 'move scratchpad'";
on-click = "${pkgs.swayfx}/bin/swaymsg 'scratchpad show'";
on-click-right = "${pkgs.swayfx}/bin/swaymsg 'move scratchpad'";
};
"custom/github" = {
format = "{} ";
return-type = "json";
interval = 60;
exec = "github-notifications";
on-click = "xdg-open https://github.com/notifications";
exec = "${pkgs.github-notifications}/bin/github-notifications";
on-click = "${pkgs.xdg-utils}/bin/xdg-open https://github.com/notifications";
};
idle_inhibitor = {
@ -235,8 +235,8 @@ in
];
};
scroll-step = 1;
on-click = "pamixer -t";
on-click-right = "pavucontrol";
on-click = "${pkgs.pamixer}/bin/pamixer -t";
on-click-right = "${pkgs.pavucontrol}/bin/pavucontrol";
};
memory = {
@ -250,13 +250,13 @@ in
interval = 5;
format-icons = [ "" "" "" "" "" "" "" "" ];
# on-click-right= "com.github.stsdc.monitor";
on-click-right = "kitty -o confirm_os_window_close=0 btm";
on-click-right = "${pkgs.kitty}/bin/kitty -o confirm_os_window_close=0 btm";
};
"custom/vpn" = {
format = "()";
exec = "echo '{\"class\": \"connected\"}'";
exec-if = "test -d /proc/sys/net/ipv4/conf/tun0";
exec-if = "${pkgs.toybox}/bin/test -d /proc/sys/net/ipv4/conf/tun0";
return-type = "json";
interval = 5;
};

View file

@ -3,7 +3,7 @@
options.swarselsystems.modules.yubikey = lib.mkEnableOption "yubikey settings";
config = lib.mkIf config.swarselsystems.modules.yubikey {
pam.yubico.authorizedYubiKeys = {
pam.yubico.authorizedYubiKeys = lib.mkIf (config.swarselsystems.isNixos && !config.swarselsystems.isPublic) {
ids = [
nixosConfig.repo.secrets.common.yubikeys.dev1
nixosConfig.repo.secrets.common.yubikeys.dev2

View file

@ -4,7 +4,6 @@ let
mkOption
types
;
in
{
options = {
@ -12,21 +11,9 @@ in
default = { };
type = types.submodule {
options = {
root = {
hashedPassword = mkOption {
type = types.str;
description = "My root user's password hash.";
};
};
myuser = {
user = {
name = mkOption {
type = types.str;
description = "My unix username.";
};
hashedPassword = mkOption {
type = types.str;
description = "My unix password hash.";
};
};
@ -37,7 +24,6 @@ in
options = {
domain = mkOption {
type = types.str;
description = "The domain under which this service can be reached";
};
};
}
@ -45,21 +31,9 @@ in
};
domains = {
me = mkOption {
main = mkOption {
type = types.str;
description = "My main domain.";
};
personal = mkOption {
type = types.str;
description = "My personal domain.";
};
};
macs = mkOption {
default = { };
type = types.attrsOf types.str;
description = "Known MAC addresses for external devices.";
};
};
};

View file

@ -1,4 +1,4 @@
{ inputs, config, lib, ... }:
{ inputs, config, lib, outputs, globals, nodes, ... }:
{
options.swarselsystems.modules.home-manager = lib.mkEnableOption "home-manager";
@ -14,7 +14,7 @@
home.stateVersion = lib.mkDefault config.system.stateVersion;
}
];
extraSpecialArgs = { inherit (inputs) self; };
extraSpecialArgs = { inherit (inputs) self; inherit inputs outputs globals nodes; };
};
};
}

View file

@ -73,6 +73,7 @@ in
"/etc/nix"
"/etc/NetworkManager/system-connections"
"/var/lib/nixos"
"/var/tmp"
{
directory = "/var/tmp/nix-import-encrypted"; # Decrypted repo-secrets can be kept
mode = "1777";

View file

@ -22,6 +22,7 @@
networkmanager = {
enable = true;
wifi.backend = "iwd";
ensureProfiles = lib.mkIf (!config.swarselsystems.isPublic) {
environmentFiles = [
"${config.sops.templates."network-manager.env".path}"

View file

@ -58,6 +58,11 @@
};
services.dbus.implementation = "broker";
systemd.services.nix-daemon = {
environment.TMPDIR = "/var/tmp";
};
system.stateVersion = lib.mkDefault "23.05";
};
}

View file

@ -0,0 +1,7 @@
{ config, lib, ... }:
{
options.swarselsystems.modules.tmp = lib.mkEnableOption "tmp dir config";
config = lib.mkIf config.swarselsystems.modules.tmp {
boot.tmp.useTmpfs = !config.swarselsystems.modules.impermanence true;
};
}

View file

@ -7,6 +7,4 @@ in
imports = lib.swarselsystems.mkImports importNames "modules/nixos/optional" ++ [
"${modulesPath}/home/common/sharedsetup.nix"
];
}

View file

@ -1,12 +1,14 @@
{ lib, config, ... }:
{ self, lib, config, globals, ... }:
let
serviceDomain = "synki.swarsel.win";
servicePort = 27701;
serviceName = "ankisync";
serviceDomain = config.repo.secrets.common.services.domains.${serviceName};
ankiUser = globals.user.name;
in
{
options.swarselsystems.modules.server."${serviceName}" = lib.mkEnableOption "enable ${serviceName} on server";
config = lib.mkIf config.swarselsystems.modules.server."${serviceName}" {
options.swarselsystems.modules.server.${serviceName} = lib.mkEnableOption "enable ${serviceName} on server";
config = lib.mkIf config.swarselsystems.modules.server.${serviceName} {
networking.firewall.allowedTCPPorts = [ servicePort ];
@ -14,6 +16,7 @@ in
topology.self.services.${serviceName} = {
name = lib.mkForce "Anki Sync Server";
icon = "${self}/topology/images/${serviceName}.png";
info = "https://${serviceDomain}";
};
@ -26,7 +29,7 @@ in
openFirewall = true;
users = [
{
username = "Swarsel";
username = ankiUser;
passwordFile = config.sops.secrets.swarsel.path;
}
];
@ -34,7 +37,7 @@ in
services.nginx = {
upstreams = {
"${serviceName}" = {
${serviceName} = {
servers = {
"192.168.1.2:${builtins.toString servicePort}" = { };
};

View file

@ -1,17 +1,17 @@
{ lib, config, ... }:
let
serviceDomain = "shellhistory.swarsel.win";
servicePort = 8888;
serviceName = "atuin";
serviceDomain = config.repo.secrets.common.services.domains.${serviceName};
in
{
options.swarselsystems.modules.server."${serviceName}" = lib.mkEnableOption "enable ${serviceName} on server";
config = lib.mkIf config.swarselsystems.modules.server."${serviceName}" {
options.swarselsystems.modules.server.${serviceName} = lib.mkEnableOption "enable ${serviceName} on server";
config = lib.mkIf config.swarselsystems.modules.server.${serviceName} {
topology.self.services.${serviceName}.info = "https://${serviceDomain}";
globals.services.${serviceName}.domain = serviceDomain;
services.atuin = {
services.${serviceName} = {
enable = true;
host = "0.0.0.0";
port = servicePort;
@ -21,7 +21,7 @@ in
nodes.moonside.services.nginx = {
upstreams = {
"${serviceName}" = {
${serviceName} = {
servers = {
"192.168.1.2:${builtins.toString servicePort}" = { };
};

View file

@ -1,6 +1,5 @@
{ self, lib, config, pkgs, ... }:
let
serviceDomain = "send.swarsel.win";
servicePorts = [
9009
9010
@ -9,12 +8,13 @@ let
9013
];
serviceName = "croc";
serviceDomain = config.repo.secrets.common.services.domains.${serviceName};
cfg = config.services.croc;
in
{
options.swarselsystems.modules.server."${serviceName}" = lib.mkEnableOption "enable ${serviceName} on server";
config = lib.mkIf config.swarselsystems.modules.server."${serviceName}" {
options.swarselsystems.modules.server.${serviceName} = lib.mkEnableOption "enable ${serviceName} on server";
config = lib.mkIf config.swarselsystems.modules.server.${serviceName} {
sops = {
secrets = {
@ -39,7 +39,7 @@ in
globals.services.${serviceName}.domain = serviceDomain;
services.croc = {
services.${serviceName} = {
enable = true;
ports = servicePorts;
pass = config.sops.secrets.croc-password.path;
@ -48,7 +48,7 @@ in
systemd.services = {
"${serviceName}" = {
${serviceName} = {
serviceConfig = {
ExecStart = lib.mkForce "${pkgs.croc}/bin/croc ${lib.optionalString cfg.debug "--debug"} relay --ports ${
lib.concatMapStringsSep "," toString cfg.ports}";

View file

@ -1,11 +1,15 @@
{ lib, config, ... }:
let
serviceName = "emacs";
servicePort = 9812;
in
{
options.swarselsystems.modules.server.emacs = lib.mkEnableOption "enable emacs server on server";
config = lib.mkIf config.swarselsystems.modules.server.emacs {
options.swarselsystems.modules.server.${serviceName} = lib.mkEnableOption "enable ${serviceName} server on server";
config = lib.mkIf config.swarselsystems.modules.server.${serviceName} {
networking.firewall.allowedTCPPorts = [ 9812 ];
networking.firewall.allowedTCPPorts = [ servicePort ];
services.emacs = {
services.${serviceName} = {
enable = true;
install = true;
startWithGraphical = false;

View file

@ -1,38 +1,47 @@
{ self, lib, config, ... }:
let
servicePort = 80;
serviceUser = "firefly-iii";
serviceGroup = serviceUser;
serviceName = "firefly-iii";
serviceDomain = config.repo.secrets.common.services.domains.${serviceName};
nginxGroup = "nginx";
cfg = config.services.firefly-iii;
serviceDomain = "stonks.swarsel.win";
fireflyUser = "firefly-iii";
serviceName = "firefly";
in
{
options.swarselsystems.modules.server.firefly = lib.mkEnableOption "enable firefly-iii on server";
config = lib.mkIf config.swarselsystems.modules.server.firefly {
options.swarselsystems.modules.server.${serviceName} = lib.mkEnableOption "enable ${serviceName} on server";
config = lib.mkIf config.swarselsystems.modules.server.${serviceName} {
users.users.firefly-iii = {
group = "nginx";
isSystemUser = true;
users = {
groups.${serviceGroup} = { };
users.${serviceUser} = {
group = lib.mkForce serviceGroup;
extraGroups = lib.mkIf cfg.enableNginx [ nginxGroup ];
isSystemUser = true;
};
};
sops = {
secrets = {
"firefly-iii-app-key" = { owner = fireflyUser; group = "nginx"; mode = "0440"; };
"firefly-iii-app-key" = { owner = serviceUser; group = if cfg.enableNginx then nginxGroup else serviceGroup; mode = "0440"; };
};
};
topology.self.services.firefly-iii = {
topology.self.services.${serviceName} = {
name = "Firefly-III";
info = "https://${serviceDomain}";
icon = "${self}/topology/images/firefly-iii.png";
icon = "${self}/topology/images/${serviceName}.png";
};
globals.services.${serviceName}.domain = serviceDomain;
services = {
firefly-iii = {
${serviceName} = {
enable = true;
user = fireflyUser;
group = if cfg.enableNginx then "nginx" else fireflyUser;
dataDir = "/Vault/data/firefly-iii";
user = serviceUser;
group = if cfg.enableNginx then nginxGroup else serviceGroup;
dataDir = "/Vault/data/${serviceName}";
settings = {
TZ = config.repo.secrets.common.location.timezone;
APP_URL = "https://${serviceDomain}";
@ -69,9 +78,9 @@ in
nodes.moonside.services.nginx = {
upstreams = {
"${serviceName}" = {
${serviceName} = {
servers = {
"192.168.1.2:80" = { };
"192.168.1.2:${builtins.toString servicePort}" = { };
};
};
};

View file

@ -1,23 +1,25 @@
{ lib, config, pkgs, ... }:
{ lib, config, pkgs, globals, ... }:
let
serviceDomain = "swagit.swarsel.win";
servicePort = 3000;
serviceUser = "forgejo";
serviceGroup = serviceUser;
serviceName = "forgejo";
serviceDomain = config.repo.secrets.common.services.domains.${serviceName};
kanidmDomain = globals.services.kanidm.domain;
in
{
options.swarselsystems.modules.server."${serviceName}" = lib.mkEnableOption "enable ${serviceName} on server";
config = lib.mkIf config.swarselsystems.modules.server."${serviceName}" {
options.swarselsystems.modules.server.${serviceName} = lib.mkEnableOption "enable ${serviceName} on server";
config = lib.mkIf config.swarselsystems.modules.server.${serviceName} {
networking.firewall.allowedTCPPorts = [ servicePort ];
users.users."${serviceUser}" = {
users.users.${serviceUser} = {
group = serviceGroup;
isSystemUser = true;
};
users.groups."${serviceGroup}" = { };
users.groups.${serviceGroup} = { };
sops.secrets = {
kanidm-forgejo-client = { owner = serviceUser; group = serviceGroup; mode = "0440"; };
@ -25,7 +27,7 @@ in
globals.services.${serviceName}.domain = serviceDomain;
services.forgejo = {
services.${serviceName} = {
enable = true;
user = serviceUser;
group = serviceGroup;
@ -67,13 +69,13 @@ in
};
};
systemd.services.forgejo = {
systemd.services.${serviceName} = {
serviceConfig.RestartSec = "60"; # Retry every minute
preStart =
let
exe = lib.getExe config.services.forgejo.package;
providerName = "kanidm";
clientId = "forgejo";
clientId = serviceName;
args = lib.escapeShellArgs (
lib.concatLists [
[
@ -90,7 +92,7 @@ in
]
[
"--auto-discover-url"
"https://sso.swarsel.win/oauth2/openid/${clientId}/.well-known/openid-configuration"
"https://${kanidmDomain}/oauth2/openid/${clientId}/.well-known/openid-configuration"
]
[
"--scopes"
@ -125,7 +127,7 @@ in
services.nginx = {
upstreams = {
"${serviceName}" = {
${serviceName} = {
servers = {
"192.168.1.2:${builtins.toString servicePort}" = { };
};

View file

@ -1,21 +1,24 @@
{ self, lib, config, ... }:
let
inherit (config.repo.secrets.local.freshrss) defaultUser;
servicePort = 80;
serviceName = "freshrss";
serviceDomain = "signpost.swarsel.win";
serviceUser = "freshrss";
serviceGroup = serviceName;
serviceDomain = config.repo.secrets.common.services.domains.${serviceName};
in
{
options.swarselsystems.modules.server.freshrss = lib.mkEnableOption "enable freshrss on server";
config = lib.mkIf config.swarselsystems.modules.server.freshrss {
options.swarselsystems.modules.server.${serviceName} = lib.mkEnableOption "enable ${serviceName} on server";
config = lib.mkIf config.swarselsystems.modules.server.${serviceName} {
users.users."${serviceUser}" = {
users.users.${serviceUser} = {
extraGroups = [ "users" ];
group = serviceGroup;
isSystemUser = true;
};
users.groups."${serviceGroup}" = { };
users.groups.${serviceGroup} = { };
sops = {
secrets = {
@ -29,7 +32,7 @@ in
# content = ''
# DATA_PATH=${config.services.freshrss.dataDir}
# OIDC_ENABLED=1
# OIDC_PROVIDER_METADATA_URL=https://sso.swarsel.win/.well-known/openid-configuration
# OIDC_PROVIDER_METADATA_URL=https://${kanidmDomain}/.well-known/openid-configuration
# OIDC_CLIENT_ID=freshrss
# OIDC_CLIENT_SECRET=${config.sops.placeholder.kanidm-freshrss-client}
# OIDC_CLIENT_CRYPTO_KEY=${config.sops.placeholder.oidc-crypto-key}
@ -47,18 +50,18 @@ in
topology.self.services.${serviceName} = {
name = "FreshRSS";
info = "https://${serviceDomain}";
icon = "${self}/topology/images/freshrss.png";
icon = "${self}/topology/images/${serviceName}.png";
};
globals.services.${serviceName}.domain = serviceDomain;
services.freshrss = {
services.${serviceName} = {
inherit defaultUser;
enable = true;
virtualHost = serviceDomain;
baseUrl = "https://${serviceDomain}";
authType = "form";
dataDir = "/Vault/data/tt-rss";
defaultUser = "Swarsel";
passwordFile = config.sops.secrets.fresh.path;
};
@ -68,9 +71,9 @@ in
nodes.moonside.services.nginx = {
upstreams = {
"${serviceName}" = {
${serviceName} = {
servers = {
"192.168.1.2:80" = { };
"192.168.1.2:${builtins.toString servicePort}" = { };
};
};
};

View file

@ -1,22 +1,22 @@
{ lib, config, globals, ... }:
let
serviceDomain = "shots.swarsel.win";
servicePort = 3001;
serviceUser = "immich";
serviceName = "immich";
serviceDomain = config.repo.secrets.common.services.domains.${serviceName};
in
{
options.swarselsystems.modules.server."${serviceName}" = lib.mkEnableOption "enable ${serviceName} on server";
config = lib.mkIf config.swarselsystems.modules.server."${serviceName}" {
options.swarselsystems.modules.server.${serviceName} = lib.mkEnableOption "enable ${serviceName} on server";
config = lib.mkIf config.swarselsystems.modules.server.${serviceName} {
users.users."${serviceUser}" = {
users.users.${serviceUser} = {
extraGroups = [ "video" "render" "users" ];
};
topology.self.services.${serviceName}.info = "https://${serviceDomain}";
globals.services.${serviceName}.domain = serviceDomain;
services.immich = {
services.${serviceName} = {
enable = true;
host = "0.0.0.0";
port = servicePort;
@ -31,7 +31,7 @@ in
nodes.moonside.services.nginx = {
upstreams = {
"${serviceName}" = {
${serviceName} = {
servers = {
"192.168.1.2:${builtins.toString servicePort}" = { };
};

View file

@ -1,14 +1,14 @@
{ pkgs, lib, config, ... }:
let
serviceDomain = "screen.swarsel.win";
servicePort = 8096;
serviceName = "jellyfin";
serviceUser = "jellyfin";
serviceDomain = config.repo.secrets.common.services.domains.${serviceName};
in
{
options.swarselsystems.modules.server."${serviceName}" = lib.mkEnableOption "enable ${serviceName} on server";
config = lib.mkIf config.swarselsystems.modules.server."${serviceName}" {
users.users."${serviceUser}" = {
options.swarselsystems.modules.server.${serviceName} = lib.mkEnableOption "enable ${serviceName} on server";
config = lib.mkIf config.swarselsystems.modules.server.${serviceName} {
users.users.${serviceUser} = {
extraGroups = [ "video" "render" "users" ];
};
nixpkgs.config.packageOverrides = pkgs: {
@ -27,7 +27,7 @@ in
topology.self.services.${serviceName}.info = "https://${serviceDomain}";
globals.services.${serviceName}.domain = serviceDomain;
services.jellyfin = {
services.${serviceName} = {
enable = true;
user = serviceUser;
openFirewall = true; # this works only for the default ports
@ -35,7 +35,7 @@ in
nodes.moonside.services.nginx = {
upstreams = {
"${serviceName}" = {
${serviceName} = {
servers = {
"192.168.1.2:${builtins.toString servicePort}" = { };
};

View file

@ -1,25 +1,25 @@
{ pkgs, lib, config, ... }:
let
serviceDomain = "servant.swarsel.win";
servicePort = 8088;
serviceName = "jenkins";
serviceDomain = config.repo.secrets.common.services.domains.${serviceName};
in
{
options.swarselsystems.modules.server."${serviceName}" = lib.mkEnableOption "enable ${serviceName} on server";
config = lib.mkIf config.swarselsystems.modules.server."${serviceName}" {
options.swarselsystems.modules.server.${serviceName} = lib.mkEnableOption "enable ${serviceName} on server";
config = lib.mkIf config.swarselsystems.modules.server.${serviceName} {
services.jenkins = {
enable = true;
withCLI = true;
port = 8088;
port = servicePort;
packages = [ pkgs.stdenv pkgs.git pkgs.jdk17 config.programs.ssh.package pkgs.nix ];
listenAddress = "0.0.0.0";
home = "/Vault/apps/jenkins";
home = "/Vault/apps/${serviceName}";
};
services.nginx = {
upstreams = {
"${serviceName}" = {
${serviceName} = {
servers = {
"192.168.1.2:${builtins.toString servicePort}" = { };
};

View file

@ -1,23 +1,30 @@
{ self, lib, pkgs, config, globals, ... }:
let
certsSopsFile = self + /secrets/certs/secrets.yaml;
serviceDomain = "sso.swarsel.win";
servicePort = 8300;
serviceUser = "kanidm";
serviceGroup = serviceUser;
serviceName = "kanidm";
serviceDomain = config.repo.secrets.common.services.domains.${serviceName};
oauth2ProxyDomain = globals.services.oauth2Proxy.domain;
immichDomain = globals.services.immich.domain;
paperlessDomain = globals.services.paperless.domain;
forgejoDomain = globals.services.forgejo.domain;
grafanaDomain = globals.services.grafana.domain;
nextcloudDomain = globals.services.nextcloud.domain;
in
{
options.swarselsystems.modules.server."${serviceName}" = lib.mkEnableOption "enable ${serviceName} on server";
config = lib.mkIf config.swarselsystems.modules.server."${serviceName}" {
options.swarselsystems.modules.server.${serviceName} = lib.mkEnableOption "enable ${serviceName} on server";
config = lib.mkIf config.swarselsystems.modules.server.${serviceName} {
users.users."${serviceUser}" = {
users.users.${serviceUser} = {
group = serviceGroup;
isSystemUser = true;
};
users.groups."${serviceGroup}" = { };
users.groups.${serviceGroup} = { };
sops = {
secrets = {
@ -40,7 +47,7 @@ in
globals.services.${serviceName}.domain = serviceDomain;
services = {
kanidm = {
${serviceName} = {
package = pkgs.kanidmWithSecretProvisioning;
enableServer = true;
serverSettings = {
@ -85,12 +92,12 @@ in
immich = {
displayName = "Immich";
originUrl = [
"https://shots.swarsel.win/auth/login"
"https://shots.swarsel.win/user-settings"
"https://${immichDomain}/auth/login"
"https://${immichDomain}/user-settings"
"app.immich:///oauth-callback"
"https://shots.swarsel.win/api/oauth/mobile-redirect"
"https://${immichDomain}/api/oauth/mobile-redirect"
];
originLanding = "https://shots.swarsel.win/";
originLanding = "https://${immichDomain}/";
basicSecretFile = config.sops.secrets.kanidm-immich.path;
preferShortUsername = true;
enableLegacyCrypto = true; # can use RS256 / HS256, not ES256
@ -102,8 +109,8 @@ in
};
paperless = {
displayName = "Paperless";
originUrl = "https://scan.swarsel.win/accounts/oidc/kanidm/login/callback/";
originLanding = "https://scan.swarsel.win/";
originUrl = "https://${paperlessDomain}/accounts/oidc/kanidm/login/callback/";
originLanding = "https://${paperlessDomain}/";
basicSecretFile = config.sops.secrets.kanidm-paperless.path;
preferShortUsername = true;
scopeMaps."paperless.access" = [
@ -114,8 +121,8 @@ in
};
forgejo = {
displayName = "Forgejo";
originUrl = "https://swagit.swarsel.win/user/oauth2/kanidm/callback";
originLanding = "https://swagit.swarsel.win/";
originUrl = "https://${forgejoDomain}/user/oauth2/kanidm/callback";
originLanding = "https://${forgejoDomain}/";
basicSecretFile = config.sops.secrets.kanidm-forgejo.path;
scopeMaps."forgejo.access" = [
"openid"
@ -133,8 +140,8 @@ in
};
grafana = {
displayName = "Grafana";
originUrl = "https://status.swarsel.win/login/generic_oauth";
originLanding = "https://status.swarsel.win/";
originUrl = "https://${grafanaDomain}/login/generic_oauth";
originLanding = "https://${grafanaDomain}/";
basicSecretFile = config.sops.secrets.kanidm-grafana.path;
preferShortUsername = true;
scopeMaps."grafana.access" = [
@ -153,8 +160,8 @@ in
};
nextcloud = {
displayName = "Nextcloud";
originUrl = " https://stash.swarsel.win/apps/sociallogin/custom_oidc/kanidm";
originLanding = "https://stash.swarsel.win/";
originUrl = " https://${nextcloudDomain}/apps/sociallogin/custom_oidc/kanidm";
originLanding = "https://${nextcloudDomain}/";
basicSecretFile = config.sops.secrets.kanidm-nextcloud.path;
allowInsecureClientDisablePkce = true;
scopeMaps."nextcloud.access" = [
@ -215,12 +222,12 @@ in
};
systemd.services = {
kanidm.serviceConfig.RestartSec = "30";
${serviceName}.serviceConfig.RestartSec = "30";
};
nodes.moonside.services.nginx = {
upstreams = {
"${serviceName}" = {
${serviceName} = {
servers = {
"192.168.1.2:${builtins.toString servicePort}" = { };
};

View file

@ -1,43 +1,43 @@
{ self, lib, config, pkgs, ... }:
let
servicePort = 8080;
serviceName = "kavita";
serviceUser = "kavita";
serviceDomain = config.repo.secrets.common.services.domains.${serviceName};
servicePort = 8080;
in
{
options.swarselsystems.modules.server."${serviceName}" = lib.mkEnableOption "enable ${serviceName} on server";
config = lib.mkIf config.swarselsystems.modules.server."${serviceName}" {
options.swarselsystems.modules.server.${serviceName} = lib.mkEnableOption "enable ${serviceName} on server";
config = lib.mkIf config.swarselsystems.modules.server.${serviceName} {
environment.systemPackages = with pkgs; [
calibre
];
users.users."${serviceUser}" = {
users.users.${serviceUser} = {
extraGroups = [ "users" ];
};
sops.secrets.kavita = { owner = serviceUser; };
networking.firewall.allowedTCPPorts = [ 8080 ];
networking.firewall.allowedTCPPorts = [ servicePort ];
topology.self.services.kavita = {
topology.self.services.${serviceName} = {
name = "Kavita";
info = "https://${serviceDomain}";
icon = "${self}/topology/images/kavita.png";
icon = "${self}/topology/images/${serviceName}.png";
};
globals.services.${serviceName}.domain = serviceDomain;
services.kavita = {
services.${serviceName} = {
enable = true;
user = serviceUser;
settings.Port = servicePort;
tokenKeyFile = config.sops.secrets.kavita.path;
dataDir = "/Vault/data/kavita";
dataDir = "/Vault/data/${serviceName}";
};
nodes.moonside.services.nginx = {
upstreams = {
"${serviceName}" = {
${serviceName} = {
servers = {
"192.168.1.2:${builtins.toString servicePort}" = { };
};

View file

@ -1,17 +1,18 @@
{ self, lib, config, ... }:
let
serviceDomain = "swag.swarsel.win";
serviceUser = "koillection";
serviceDB = "koillection";
serviceName = "koillection";
servicePort = 2282;
serviceDomain = config.repo.secrets.common.services.domains.${serviceName};
postgresUser = config.systemd.services.postgresql.serviceConfig.User; # postgres
postgresPort = config.services.postgresql.settings.port; # 5432
containerRev = "sha256:96693e41a6eb2aae44f96033a090378270f024ddf4e6095edf8d57674f21095d";
in
{
options.swarselsystems.modules.server."${serviceName}" = lib.mkEnableOption "enable ${serviceName} on server";
config = lib.mkIf config.swarselsystems.modules.server."${serviceName}" {
options.swarselsystems.modules.server.${serviceName} = lib.mkEnableOption "enable ${serviceName} on server";
config = lib.mkIf config.swarselsystems.modules.server.${serviceName} {
sops.secrets = {
koillection-db-password = { owner = postgresUser; group = postgresUser; mode = "0440"; };
@ -97,7 +98,7 @@ in
nodes.moonside.services.nginx = {
upstreams = {
"${serviceName}" = {
${serviceName} = {
servers = {
"192.168.1.2:${builtins.toString servicePort}" = { };
};

View file

@ -1,16 +1,17 @@
{ lib, config, pkgs, ... }:
let
matrixDomain = "swatrix.swarsel.win";
servicePort = 8008;
serviceName = "matrix";
synapsePort = 8008;
synapseUser = "matrix-synapse";
serviceDomain = config.repo.secrets.common.services.domains.matrix;
serviceUser = "matrix-synapse";
federationPort = 8448;
whatsappPort = 29318;
telegramPort = 29317;
signalPort = 29328;
baseUrl = "https://${matrixDomain}";
baseUrl = "https://${serviceDomain}";
clientConfig."m.homeserver".base_url = baseUrl;
serverConfig."m.server" = "${matrixDomain}:443";
serverConfig."m.server" = "${serviceDomain}:443";
mkWellKnown = data: ''
default_type application/json;
add_header Access-Control-Allow-Origin *;
@ -18,8 +19,8 @@ let
'';
in
{
options.swarselsystems.modules.server."${serviceName}" = lib.mkEnableOption "enable ${serviceName} on server";
config = lib.mkIf config.swarselsystems.modules.server."${serviceName}" {
options.swarselsystems.modules.server.${serviceName} = lib.mkEnableOption "enable ${serviceName} on server";
config = lib.mkIf config.swarselsystems.modules.server.${serviceName} {
environment.systemPackages = with pkgs; [
matrix-synapse
lottieconverter
@ -28,24 +29,24 @@ in
sops = {
secrets = {
matrixsharedsecret = { owner = synapseUser; };
mautrixtelegram_as = { owner = synapseUser; };
mautrixtelegram_hs = { owner = synapseUser; };
mautrixtelegram_api_id = { owner = synapseUser; };
mautrixtelegram_api_hash = { owner = synapseUser; };
matrixsharedsecret = { owner = serviceUser; };
mautrixtelegram_as = { owner = serviceUser; };
mautrixtelegram_hs = { owner = serviceUser; };
mautrixtelegram_api_id = { owner = serviceUser; };
mautrixtelegram_api_hash = { owner = serviceUser; };
};
templates = {
"matrix_user_register.sh".content = ''
register_new_matrix_user -k ${config.sops.placeholder.matrixsharedsecret} http://localhost:${builtins.toString synapsePort}
register_new_matrix_user -k ${config.sops.placeholder.matrixsharedsecret} http://localhost:${builtins.toString servicePort}
'';
matrixshared = {
owner = synapseUser;
owner = serviceUser;
content = ''
registration_shared_secret: ${config.sops.placeholder.matrixsharedsecret}
'';
};
mautrixtelegram = {
owner = synapseUser;
owner = serviceUser;
content = ''
MAUTRIX_TELEGRAM_APPSERVICE_AS_TOKEN=${config.sops.placeholder.mautrixtelegram_as}
MAUTRIX_TELEGRAM_APPSERVICE_HS_TOKEN=${config.sops.placeholder.mautrixtelegram_hs}
@ -56,7 +57,7 @@ in
};
};
networking.firewall.allowedTCPPorts = [ 8008 8448 ];
networking.firewall.allowedTCPPorts = [ servicePort federationPort ];
systemd = {
timers."restart-bridges" = {
@ -87,7 +88,7 @@ in
};
};
globals.services.${serviceName}.domain = matrixDomain;
globals.services.${serviceName}.domain = serviceDomain;
services = {
postgresql = {
@ -130,11 +131,11 @@ in
"${dataDir}/signal-registration.yaml"
"${dataDir}/doublepuppet.yaml"
];
server_name = matrixDomain;
public_baseurl = "https://${matrixDomain}";
server_name = serviceDomain;
public_baseurl = "https://${serviceDomain}";
listeners = [
{
port = synapsePort;
port = servicePort;
bind_addresses = [
"0.0.0.0"
# "::1"
@ -162,8 +163,8 @@ in
registerToSynapse = false;
settings = {
homeserver = {
address = "http://localhost:${builtins.toString synapsePort}";
domain = matrixDomain;
address = "http://localhost:${builtins.toString servicePort}";
domain = serviceDomain;
};
appservice = {
address = "http://localhost:${builtins.toString telegramPort}";
@ -188,7 +189,7 @@ in
telegram_link_preview = true;
permissions = {
"*" = "relaybot";
"@swarsel:${matrixDomain}" = "admin";
"@swarsel:${serviceDomain}" = "admin";
};
animated_sticker = {
target = "gif";
@ -208,8 +209,8 @@ in
registerToSynapse = false;
settings = {
homeserver = {
address = "http://localhost:${builtins.toString synapsePort}";
domain = matrixDomain;
address = "http://localhost:${builtins.toString servicePort}";
domain = serviceDomain;
};
appservice = {
address = "http://localhost:${builtins.toString whatsappPort}";
@ -234,7 +235,7 @@ in
};
};
login_shared_secret_map = {
matrixDomain = "as_token:doublepuppet";
${serviceDomain} = "as_token:doublepuppet";
};
sync_manual_marked_unread = true;
send_presence_on_typing = true;
@ -244,7 +245,7 @@ in
extev_polls = true;
permissions = {
"*" = "relay";
"@swarsel:${matrixDomain}" = "admin";
"@swarsel:${serviceDomain}" = "admin";
};
};
};
@ -255,8 +256,8 @@ in
registerToSynapse = false;
settings = {
homeserver = {
address = "http://localhost:${builtins.toString synapsePort}";
domain = matrixDomain;
address = "http://localhost:${builtins.toString servicePort}";
domain = serviceDomain;
};
appservice = {
address = "http://localhost:${builtins.toString signalPort}";
@ -270,12 +271,12 @@ in
bridge = {
displayname_template = "{{or .ContactName .ProfileName .PhoneNumber}} (Signal)";
login_shared_secret_map = {
matrixDomain = "as_token:doublepuppet";
${serviceDomain} = "as_token:doublepuppet";
};
caption_in_message = true;
permissions = {
"*" = "relay";
"@swarsel:${matrixDomain}" = "admin";
"@swarsel:${serviceDomain}" = "admin";
};
};
};
@ -288,14 +289,14 @@ in
nodes.moonside.services.nginx = {
upstreams = {
"${serviceName}" = {
${serviceName} = {
servers = {
"192.168.1.2:${builtins.toString synapsePort}" = { };
"192.168.1.2:${builtins.toString servicePort}" = { };
};
};
};
virtualHosts = {
"${matrixDomain}" = {
"${serviceDomain}" = {
enableACME = true;
forceSSL = true;
acmeRoot = null;

View file

@ -1,21 +1,21 @@
{ self, lib, config, ... }:
let
serviceDomain = "scratch.swarsel.win";
servicePort = 8777;
serviceName = "microbin";
serviceUser = "microbin";
serviceGroup = serviceUser;
serviceDomain = config.repo.secrets.common.services.domains.${serviceName};
cfg = config.services."${serviceName}";
cfg = config.services.${serviceName};
in
{
options.swarselsystems.modules.server."${serviceName}" = lib.mkEnableOption "enable ${serviceName} on server";
config = lib.mkIf config.swarselsystems.modules.server."${serviceName}" {
options.swarselsystems.modules.server.${serviceName} = lib.mkEnableOption "enable ${serviceName} on server";
config = lib.mkIf config.swarselsystems.modules.server.${serviceName} {
users = {
groups."${serviceGroup}" = { };
groups.${serviceGroup} = { };
users."${serviceUser}" = {
users.${serviceUser} = {
isSystemUser = true;
group = serviceGroup;
};
@ -49,7 +49,7 @@ in
};
globals.services.${serviceName}.domain = serviceDomain;
services."${serviceName}" = {
services.${serviceName} = {
enable = true;
passwordFile = config.sops.templates.microbin-env.path;
dataDir = "/var/lib/microbin";
@ -84,7 +84,7 @@ in
};
systemd.services = {
"${serviceName}" = {
${serviceName} = {
serviceConfig = {
DynamicUser = lib.mkForce false;
User = serviceUser;
@ -101,7 +101,7 @@ in
services.nginx = {
upstreams = {
"${serviceName}" = {
${serviceName} = {
servers = {
"localhost:${builtins.toString servicePort}" = { };
};

View file

@ -1,23 +1,44 @@
{ self, lib, config, ... }:
{ self, lib, config, globals, ... }:
let
serviceDomain = "status.swarsel.win";
servicePort = 3000;
serviceUser = "grafana";
serviceGroup = serviceUser;
moduleName = "monitoring";
serviceName = "grafana";
serviceDomain = config.repo.secrets.common.services.domains.${serviceName};
prometheusPort = 9090;
prometheusUser = "prometheus";
prometheusGroup = prometheusUser;
nextcloudUser = config.repo.secrets.local.nextcloud.adminuser;
grafanaUpstream = "grafana";
prometheusUpstream = "prometheus";
prometheusPort = 9090;
prometheusWebRoot = "prometheus";
kanidmDomain = globals.services.kanidm.domain;
in
{
options.swarselsystems.modules.server."${moduleName}" = lib.mkEnableOption "enable ${moduleName} on server";
config = lib.mkIf config.swarselsystems.modules.server."${moduleName}" {
options.swarselsystems.modules.server.${serviceName} = lib.mkEnableOption "enable ${serviceName} on server";
config = lib.mkIf config.swarselsystems.modules.server.${serviceName} {
sops.secrets = {
grafanaadminpass = { owner = serviceUser; group = serviceGroup; mode = "0440"; };
prometheusadminpass = { owner = serviceUser; group = serviceGroup; mode = "0440"; };
kanidm-grafana-client = { owner = serviceUser; group = serviceGroup; mode = "0440"; };
sops = {
secrets = {
grafanaadminpass = { owner = serviceUser; group = serviceGroup; mode = "0440"; };
prometheusadminpass = { owner = serviceUser; group = serviceGroup; mode = "0440"; };
kanidm-grafana-client = { owner = serviceUser; group = serviceGroup; mode = "0440"; };
prometheus-admin-hash = { sopsFile = self + /secrets/winters/secrets2.yaml; owner = prometheusUser; group = prometheusGroup; mode = "0440"; };
};
templates = {
"web-config" = {
content = ''
basic_auth_users:
admin: ${config.sops.placeholder.prometheus-admin-hash}
'';
owner = prometheusUser;
group = prometheusGroup;
mode = "0440";
};
};
};
users = {
@ -26,7 +47,7 @@ in
extraGroups = [ "nextcloud" ];
};
"${serviceUser}" = {
${serviceUser} = {
extraGroups = [ "users" ];
};
};
@ -35,12 +56,12 @@ in
networking.firewall.allowedTCPPorts = [ servicePort prometheusPort ];
topology.self.services.prometheus.info = "https://${serviceDomain}/${prometheusWebRoot}";
globals.services.${moduleName}.domain = serviceDomain;
globals.services.${serviceName}.domain = serviceDomain;
services = {
grafana = {
${serviceName} = {
enable = true;
dataDir = "/Vault/data/grafana";
dataDir = "/Vault/data/${serviceName}";
provision = {
enable = true;
datasources.settings = {
@ -97,9 +118,9 @@ in
client_secret = "$__file{${config.sops.secrets.kanidm-grafana-client.path}}";
scopes = "openid email profile";
login_attribute_path = "preferred_username";
auth_url = "https://sso.swarsel.win/ui/oauth2";
token_url = "https://sso.swarsel.win/oauth2/token";
api_url = "https://sso.swarsel.win/oauth2/openid/grafana/userinfo";
auth_url = "https://${kanidmDomain}/ui/oauth2";
token_url = "https://${kanidmDomain}/oauth2/token";
api_url = "https://${kanidmDomain}/oauth2/openid/grafana/userinfo";
use_pkce = true;
use_refresh_token = true;
# Allow mapping oauth2 roles to server admin
@ -111,13 +132,13 @@ in
prometheus = {
enable = true;
webExternalUrl = "https://status.swarsel.win/${prometheusWebRoot}";
webExternalUrl = "https://${serviceDomain}/${prometheusWebRoot}";
port = prometheusPort;
listenAddress = "0.0.0.0";
globalConfig = {
scrape_interval = "10s";
};
webConfigFile = self + /programs/server/prometheus/web.config;
webConfigFile = config.sops.templates.web-config.path;
scrapeConfigs = [
{
job_name = "node";
@ -171,8 +192,8 @@ in
nextcloud = lib.mkIf config.swarselsystems.modules.server.nextcloud {
enable = true;
port = 9205;
url = "https://stash.swarsel.win/ocs/v2.php/apps/serverinfo/api/v1/info";
username = "admin";
url = "https://${serviceDomain}/ocs/v2.php/apps/serverinfo/api/v1/info";
username = nextcloudUser;
passwordFile = config.sops.secrets.nextcloudadminpass.path;
};
};

View file

@ -1,23 +1,29 @@
{ self, lib, config, pkgs, ... }:
let
servicePort = 3254;
serviceUser = "mpd";
serviceGroup = serviceUser;
serviceName = "mpd";
in
{
options.swarselsystems.modules.server.mpd = lib.mkEnableOption "enable mpd on server";
config = lib.mkIf config.swarselsystems.modules.server.mpd {
options.swarselsystems.modules.server.${serviceName} = lib.mkEnableOption "enable ${serviceName} on server";
config = lib.mkIf config.swarselsystems.modules.server.${serviceName} {
users = {
groups = {
mpd = { };
};
users = {
mpd = {
${serviceUser} = {
isSystemUser = true;
group = "mpd";
group = serviceGroup;
extraGroups = [ "audio" "utmp" ];
};
};
};
sops = {
secrets.mpdpass = { owner = "mpd"; };
secrets.mpdpass = { owner = serviceUser; group = serviceGroup; mode = "0440"; };
};
environment.systemPackages = with pkgs; [
@ -26,19 +32,19 @@
mpv
];
topology.self.services.mpd = {
name = "MPD";
info = "http://localhost:3254";
icon = "${self}/topology/images/mpd.png";
topology.self.services.${serviceName} = {
name = lib.toUpper serviceName;
info = "http://localhost:${builtins.toString servicePort}";
icon = "${self}/topology/images/${serviceName}.png";
};
services.mpd = {
services.${serviceName} = {
enable = true;
musicDirectory = "/media";
user = "mpd";
group = "mpd";
user = serviceUser;
group = serviceGroup;
network = {
port = 3254;
port = servicePort;
listenAddress = "any";
};
credentials = [

View file

@ -1,14 +1,14 @@
{ pkgs, config, lib, ... }:
let
serviceDomain = "sound.swarsel.win";
servicePort = 4040;
serviceName = "navidrome";
serviceUser = "navidrome";
serviceGroup = serviceUser;
serviceDomain = config.repo.secrets.common.services.domains.${serviceName};
in
{
options.swarselsystems.modules.server."${serviceName}" = lib.mkEnableOption "enable ${serviceName} on server";
config = lib.mkIf config.swarselsystems.modules.server."${serviceName}" {
options.swarselsystems.modules.server.${serviceName} = lib.mkEnableOption "enable ${serviceName} on server";
config = lib.mkIf config.swarselsystems.modules.server.${serviceName} {
environment.systemPackages = with pkgs; [
pciutils
alsa-utils
@ -17,13 +17,13 @@ in
users = {
groups = {
"${serviceGroup}" = {
${serviceGroup} = {
gid = 61593;
};
};
users = {
"${serviceUser}" = {
${serviceUser} = {
isSystemUser = true;
uid = 61593;
group = serviceGroup;
@ -36,11 +36,11 @@ in
enableAllFirmware = lib.mkForce true;
};
networking.firewall.allowedTCPPorts = [ 4040 ];
networking.firewall.allowedTCPPorts = [ servicePort ];
globals.services.${serviceName}.domain = serviceDomain;
services.navidrome = {
services.${serviceName} = {
enable = true;
openFirewall = true;
settings = {
@ -82,7 +82,7 @@ in
nodes.moonside.services.nginx = {
upstreams = {
"${serviceName}" = {
${serviceName} = {
servers = {
"192.168.1.2:${builtins.toString servicePort}" = { };
};
@ -108,19 +108,19 @@ in
in
{
"/" = {
proxyPass = "http://navidrome";
proxyPass = "http://${serviceName}";
proxyWebsockets = true;
inherit extraConfig;
};
"/share" = {
proxyPass = "http://navidrome";
proxyPass = "http://${serviceName}";
proxyWebsockets = true;
setOauth2Headers = false;
bypassAuth = true;
inherit extraConfig;
};
"/rest" = {
proxyPass = "http://navidrome";
proxyPass = "http://${serviceName}";
proxyWebsockets = true;
setOauth2Headers = false;
bypassAuth = true;

View file

@ -1,13 +1,16 @@
{ pkgs, lib, config, ... }:
let
serviceDomain = "stash.swarsel.win";
inherit (config.repo.secrets.local.nextcloud) adminuser;
servicePort = 80;
serviceUser = "nextcloud";
serviceGroup = serviceUser;
serviceName = "nextcloud";
serviceDomain = config.repo.secrets.common.services.domains.${serviceName};
in
{
options.swarselsystems.modules.server."${serviceName}" = lib.mkEnableOption "enable ${serviceName} on server";
config = lib.mkIf config.swarselsystems.modules.server."${serviceName}" {
options.swarselsystems.modules.server.${serviceName} = lib.mkEnableOption "enable ${serviceName} on server";
config = lib.mkIf config.swarselsystems.modules.server.${serviceName} {
sops.secrets = {
nextcloudadminpass = {
@ -26,7 +29,7 @@ in
globals.services.${serviceName}.domain = serviceDomain;
services = {
nextcloud = {
${serviceName} = {
enable = true;
settings = {
trusted_proxies = [ "0.0.0.0" ];
@ -34,8 +37,8 @@ in
};
package = pkgs.nextcloud31;
hostName = serviceDomain;
home = "/Vault/data/nextcloud";
datadir = "/Vault/data/nextcloud";
home = "/Vault/data/${serviceName}";
datadir = "/Vault/data/${serviceName}";
https = true;
configureRedis = true;
maxUploadSize = "4G";
@ -44,7 +47,7 @@ in
};
extraAppsEnable = true;
config = {
adminuser = "admin";
inherit adminuser;
adminpassFile = config.sops.secrets.nextcloudadminpass.path;
dbtype = "sqlite";
};
@ -53,9 +56,9 @@ in
nodes.moonside.services.nginx = {
upstreams = {
"${serviceName}" = {
${serviceName} = {
servers = {
"192.168.1.2:80" = { };
"192.168.1.2:${builtins.toString servicePort}" = { };
};
};
};

View file

@ -1,4 +1,7 @@
{ lib, config, pkgs, ... }:
{ lib, config, pkgs, globals, ... }:
let
nfsUser = globals.user.name;
in
{
options.swarselsystems.modules.server.nfs = lib.mkEnableOption "enable nfs on server";
config = lib.mkIf config.swarselsystems.modules.server.nfs {
@ -29,7 +32,7 @@
path = "/Vault/Eternor";
writable = "true";
comment = "Eternor";
"valid users" = "Swarsel";
"valid users" = nfsUser;
};
};

View file

@ -1,4 +1,8 @@
{ pkgs, lib, config, ... }:
let
inherit (config.repo.secrets.common) dnsProvider;
inherit (config.repo.secrets.common.mail) address3;
in
{
options.swarselsystems.modules.server.nginx = lib.mkEnableOption "enable nginx on server";
config = lib.mkIf config.swarselsystems.modules.server.nginx {
@ -18,8 +22,8 @@
acceptTerms = true;
preliminarySelfsigned = false;
defaults = {
email = "mrswarsel@gmail.com";
dnsProvider = "cloudflare";
inherit dnsProvider;
email = address3;
environmentFile = "${config.sops.templates."certs.secret".path}";
};
};

View file

@ -1,12 +1,17 @@
{ lib, config, globals, ... }:
let
servicePort = 3004;
serviceUser = "oauth2-proxy";
serviceGroup = serviceUser;
serviceName = "oauth2-proxy";
serviceDomain = config.repo.secrets.common.services.domains.${serviceName};
kanidmDomain = globals.services.kanidm.domain;
oauth2ProxyDomain = "soauth.swarsel.win";
oauth2ProxyPort = 3004;
mainDomain = globals.domains.main;
in
{
options = {
swarselsystems.modules.server.oauth2Proxy = lib.mkEnableOption "enable oauth2-proxy on server";
swarselsystems.modules.server.${serviceName} = lib.mkEnableOption "enable ${serviceName} on server";
# largely based on https://github.com/oddlama/nix-config/blob/main/modules/oauth2-proxy.nix
services.nginx.virtualHosts = lib.mkOption {
type = lib.types.attrsOf (
@ -114,12 +119,12 @@ in
);
};
};
config = lib.mkIf config.swarselsystems.modules.server.oauth2Proxy {
config = lib.mkIf config.swarselsystems.modules.server.${serviceName} {
sops = {
secrets = {
"oauth2-cookie-secret" = { owner = "oauth2-proxy"; group = "oauth2-proxy"; mode = "0440"; };
"kanidm-oauth2-proxy-client" = { owner = "oauth2-proxy"; group = "oauth2-proxy"; mode = "0440"; };
"oauth2-cookie-secret" = { owner = serviceUser; group = serviceGroup; mode = "0440"; };
"kanidm-oauth2-proxy-client" = { owner = serviceUser; group = serviceGroup; mode = "0440"; };
};
templates = {
@ -128,34 +133,34 @@ in
OAUTH2_PROXY_CLIENT_SECRET="${config.sops.placeholder.kanidm-oauth2-proxy-client}"
OAUTH2_PROXY_COOKIE_SECRET=${config.sops.placeholder.oauth2-cookie-secret}
'';
owner = "oauth2-proxy";
group = "oauth2-proxy";
owner = serviceUser;
group = serviceGroup;
mode = "0440";
};
};
};
networking.firewall.allowedTCPPorts = [ oauth2ProxyPort ];
networking.firewall.allowedTCPPorts = [ servicePort ];
globals.services.oauth2Proxy.domain = oauth2ProxyDomain;
globals.services.oauth2Proxy.domain = serviceDomain;
services = {
oauth2-proxy = {
${serviceName} = {
enable = true;
cookie = {
domain = ".swarsel.win";
domain = ".${mainDomain}";
secure = true;
expire = "900m";
secret = null; # set by service EnvironmentFile
};
clientSecret = null; # set by service EnvironmentFile
reverseProxy = true;
httpAddress = "0.0.0.0:${builtins.toString oauth2ProxyPort}";
redirectURL = "https://${oauth2ProxyDomain}/oauth2/callback";
httpAddress = "0.0.0.0:${builtins.toString servicePort}";
redirectURL = "https://${serviceDomain}/oauth2/callback";
setXauthrequest = true;
extraConfig = {
code-challenge-method = "S256";
whitelist-domain = ".swarsel.win";
whitelist-domain = ".${mainDomain}";
set-authorization-header = true;
pass-access-token = true;
skip-jwt-bearer-tokens = true;
@ -168,16 +173,16 @@ in
loginURL = "https://${kanidmDomain}/ui/oauth2";
redeemURL = "https://${kanidmDomain}/oauth2/token";
validateURL = "https://${kanidmDomain}/oauth2/openid/oauth2-proxy/userinfo";
clientID = "oauth2-proxy";
clientID = serviceName;
email.domains = [ "*" ];
};
};
systemd.services = {
oauth2-proxy = {
${serviceName} = {
# after = [ "kanidm.service" ];
serviceConfig = {
RuntimeDirectory = "oauth2-proxy";
RuntimeDirectory = serviceName;
RuntimeDirectoryMode = "0750";
UMask = "007"; # TODO remove once https://github.com/oauth2-proxy/oauth2-proxy/issues/2141 is fixed
RestartSec = "60"; # Retry every minute
@ -190,20 +195,20 @@ in
services.nginx = {
upstreams = {
oauth2-proxy = {
${serviceName} = {
servers = {
"localhost:${builtins.toString oauth2ProxyPort}" = { };
"localhost:${builtins.toString servicePort}" = { };
};
};
};
virtualHosts = {
"${oauth2ProxyDomain}" = {
"${serviceDomain}" = {
enableACME = true;
forceSSL = true;
acmeRoot = null;
locations = {
"/" = {
proxyPass = "http://oauth2-proxy";
proxyPass = "http://${serviceName}";
};
};
extraConfig = ''

View file

@ -1,16 +1,20 @@
{ lib, pkgs, config, ... }:
{ lib, pkgs, config, globals, ... }:
let
serviceDomain = "scan.swarsel.win";
servicePort = 28981;
serviceUser = "paperless";
serviceGroup = serviceUser;
serviceName = "paperless";
serviceDomain = config.repo.secrets.common.services.domains.${serviceName};
tikaPort = 9998;
gotenbergPort = 3002;
kanidmDomain = globals.services.kanidm.domain;
in
{
options.swarselsystems.modules.server."${serviceName}" = lib.mkEnableOption "enable ${serviceName} on server";
config = lib.mkIf config.swarselsystems.modules.server."${serviceName}" {
options.swarselsystems.modules.server.${serviceName} = lib.mkEnableOption "enable ${serviceName} on server";
config = lib.mkIf config.swarselsystems.modules.server.${serviceName} {
users.users."${serviceUser}" = {
users.users.${serviceUser} = {
extraGroups = [ "users" ];
};
@ -28,25 +32,25 @@ in
globals.services.${serviceName}.domain = serviceDomain;
services = {
paperless = {
${serviceName} = {
enable = true;
mediaDir = "/Vault/Eternor/Paperless";
dataDir = "/Vault/data/paperless";
dataDir = "/Vault/data/${serviceName}";
user = serviceUser;
port = servicePort;
passwordFile = config.sops.secrets.paperless_admin.path;
address = "0.0.0.0";
settings = {
PAPERLESS_OCR_LANGUAGE = "deu+eng";
PAPERLESS_URL = "https://scan.swarsel.win";
PAPERLESS_URL = "https://${serviceDomain}";
PAPERLESS_OCR_USER_ARGS = builtins.toJSON {
optimize = 1;
invalidate_digital_signatures = true;
pdfa_image_compression = "lossless";
};
PAPERLESS_TIKA_ENABLED = "true";
PAPERLESS_TIKA_ENDPOINT = "http://localhost:9998";
PAPERLESS_TIKA_GOTENBERG_ENDPOINT = "http://localhost:3002";
PAPERLESS_TIKA_ENDPOINT = "http://localhost:${builtins.toString tikaPort}";
PAPERLESS_TIKA_GOTENBERG_ENDPOINT = "http://localhost:${builtins.toString gotenbergPort}";
PAPERLESS_APPS = "allauth.socialaccount.providers.openid_connect";
PAPERLESS_SOCIALACCOUNT_PROVIDERS = builtins.toJSON {
openid_connect = {
@ -58,7 +62,7 @@ in
client_id = "paperless";
# secret will be added by paperless-web.service (see below)
#secret = "";
settings.server_url = "https://sso.swarsel.win/oauth2/openid/${client_id}/.well-known/openid-configuration";
settings.server_url = "https://${kanidmDomain}/oauth2/openid/${client_id}/.well-known/openid-configuration";
}
];
};
@ -68,7 +72,7 @@ in
tika = {
enable = true;
port = 9998;
port = tikaPort;
openFirewall = false;
listenAddress = "127.0.0.1";
enableOcr = true;
@ -77,7 +81,7 @@ in
gotenberg = {
enable = true;
package = pkgs.stable.gotenberg;
port = 3002;
port = gotenbergPort;
bindIP = "127.0.0.1";
timeout = "600s";
chromium.package = pkgs.stable.chromium;
@ -97,7 +101,7 @@ in
nodes.moonside.services.nginx = {
upstreams = {
"${serviceName}" = {
${serviceName} = {
servers = {
"192.168.1.2:${builtins.toString servicePort}" = { };
};

View file

@ -4,13 +4,13 @@ let
postgresVersion = 14;
in
{
options.swarselsystems.modules.server."${serviceName}" = lib.mkEnableOption "enable ${serviceName} on server";
config = lib.mkIf config.swarselsystems.modules.server."${serviceName}" {
options.swarselsystems.modules.server.${serviceName} = lib.mkEnableOption "enable ${serviceName} on server";
config = lib.mkIf config.swarselsystems.modules.server.${serviceName} {
services = {
postgresql = {
${serviceName} = {
enable = true;
package = pkgs."postgresql_${builtins.toString postgresVersion}";
dataDir = "/Vault/data/postgresql/${builtins.toString postgresVersion}";
dataDir = "/Vault/data/${serviceName}/${builtins.toString postgresVersion}";
};
};
};

View file

@ -2,17 +2,18 @@
let
inherit (config.repo.secrets.local.radicale) user1;
sopsFile = self + /secrets/winters/secrets2.yaml;
serviceDomain = "schedule.swarsel.win";
servicePort = 8000;
serviceName = "radicale";
serviceUser = "radicale";
serviceGroup = serviceUser;
serviceDomain = config.repo.secrets.common.services.domains.${serviceName};
cfg = config.services."${serviceName}";
cfg = config.services.${serviceName};
in
{
options.swarselsystems.modules.server."${serviceName}" = lib.mkEnableOption "enable ${serviceName} on server";
config = lib.mkIf config.swarselsystems.modules.server."${serviceName}" {
options.swarselsystems.modules.server.${serviceName} = lib.mkEnableOption "enable ${serviceName} on server";
config = lib.mkIf config.swarselsystems.modules.server.${serviceName} {
sops = {
secrets.radicale-user = { inherit sopsFile; owner = serviceUser; group = serviceGroup; mode = "0440"; };
@ -32,7 +33,7 @@ in
topology.self.services.${serviceName}.info = "https://${serviceDomain}";
globals.services.${serviceName}.domain = serviceDomain;
services.radicale = {
services.${serviceName} = {
enable = true;
settings = {
server = {
@ -75,11 +76,10 @@ in
];
networking.firewall.allowedTCPPorts = [ servicePort ];
networking.firewall.allowedUDPPorts = [ servicePort ];
nodes.moonside.services.nginx = {
upstreams = {
"${serviceName}" = {
${serviceName} = {
servers = {
"192.168.1.2:${builtins.toString servicePort}" = { };
};

View file

@ -1,15 +1,16 @@
{ self, lib, config, ... }:
let
serviceDomain = "s.swarsel.win";
servicePort = 8081;
serviceName = "shlink";
serviceDomain = config.repo.secrets.common.services.domains.${serviceName};
containerRev = "sha256:1a697baca56ab8821783e0ce53eb4fb22e51bb66749ec50581adc0cb6d031d7a";
in
{
options = {
swarselsystems.modules.server."${serviceName}" = lib.mkEnableOption "enable ${serviceName} on server";
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} {
sops = {
secrets = {
@ -25,7 +26,7 @@ in
};
};
virtualisation.oci-containers.containers."shlink" = {
virtualisation.oci-containers.containers.${serviceName} = {
image = "shlinkio/shlink@${containerRev}";
environment = {
"DEFAULT_DOMAIN" = serviceDomain;
@ -57,7 +58,7 @@ in
services.nginx = {
upstreams = {
"${serviceName}" = {
${serviceName} = {
servers = {
"localhost:${builtins.toString servicePort}" = { };
};

View file

@ -6,13 +6,13 @@ let
serviceGroup = serviceUser;
in
{
options.swarselsystems.modules.server."${serviceName}" = lib.mkEnableOption "enable ${serviceName} on server";
config = lib.mkIf config.swarselsystems.modules.server."${serviceName}" {
users.groups."${serviceGroup}" = {
options.swarselsystems.modules.server.${serviceName} = lib.mkEnableOption "enable ${serviceName} on server";
config = lib.mkIf config.swarselsystems.modules.server.${serviceName} {
users.groups.${serviceGroup} = {
gid = 65136;
};
users.users."${serviceUser}" = {
users.users.${serviceUser} = {
isSystemUser = true;
uid = 65136;
group = serviceGroup;

View file

@ -1,34 +1,37 @@
{ lib, config, ... }:
let
inherit (config.repo.secrets.common) workHostName;
serviceDomain = "storync.swarsel.win";
servicePort = 8384;
serviceUser = "syncthing";
serviceGroup = serviceUser;
serviceName = "syncthing";
serviceDomain = config.repo.secrets.common.services.domains.syncthing1;
cfg = config.services.${serviceName};
in
{
options.swarselsystems.modules.server."${serviceName}" = lib.mkEnableOption "enable ${serviceName} on server";
config = lib.mkIf config.swarselsystems.modules.server."${serviceName}" {
options.swarselsystems.modules.server.${serviceName} = lib.mkEnableOption "enable ${serviceName} on server";
config = lib.mkIf config.swarselsystems.modules.server.${serviceName} {
users.users."${serviceUser}" = {
users.users.${serviceUser} = {
extraGroups = [ "users" ];
group = serviceGroup;
isSystemUser = true;
};
users.groups."${serviceGroup}" = { };
users.groups.${serviceGroup} = { };
networking.firewall.allowedTCPPorts = [ servicePort ];
globals.services.${serviceName}.domain = serviceDomain;
globals.services."${serviceName}-${config.networking.hostName}".domain = serviceDomain;
services.syncthing = {
services.${serviceName} = rec {
enable = true;
user = serviceUser;
group = serviceGroup;
dataDir = "/Vault/data/syncthing";
configDir = "/Vault/data/syncthing/.config/syncthing";
dataDir = "/Vault/data/${serviceName}";
configDir = "${cfg.dataDir}/.config/${serviceName}";
guiAddress = "0.0.0.0:${builtins.toString servicePort}";
openDefaultPorts = true; # opens ports TCP/UDP 22000 and UDP 21027 for discovery
relay.enable = false;
@ -50,14 +53,14 @@ in
};
folders = {
"Default Folder" = lib.mkForce {
path = "/Vault/data/syncthing/Sync";
path = "${cfg.dataDir}/Sync";
type = "receiveonly";
versioning = null;
devices = [ "sync@oracle" "magicant" "${workHostName}" "moonside@oracle" ];
id = "default";
};
"Obsidian" = {
path = "/Vault/data/syncthing/Obsidian";
path = "${cfg.dataDir}/Obsidian";
type = "receiveonly";
versioning = {
type = "simple";
@ -67,7 +70,7 @@ in
id = "yjvni-9eaa7";
};
"Org" = {
path = "/Vault/data/syncthing/Org";
path = "${cfg.dataDir}/Org";
type = "receiveonly";
versioning = {
type = "simple";
@ -77,7 +80,7 @@ in
id = "a7xnl-zjj3d";
};
"Vpn" = {
path = "/Vault/data/syncthing/Vpn";
path = "${cfg.dataDir}/Vpn";
type = "receiveonly";
versioning = {
type = "simple";
@ -87,7 +90,7 @@ in
id = "hgp9s-fyq3p";
};
# "Documents" = {
# path = "/Vault/data/syncthing/Documents";
# path = "${cfg.dataDir}/Documents";
# type = "receiveonly";
# versioning = {
# type = "simple";
@ -102,7 +105,7 @@ in
nodes.moonside.services.nginx = {
upstreams = {
"${serviceName}" = {
${serviceName} = {
servers = {
"192.168.1.2:${builtins.toString servicePort}" = { };
};

View file

@ -1,6 +1,8 @@
{ self, pkgs, lib, config, ... }:
let
serviceDomain = "store.swarsel.win";
serviceName = "transmission";
serviceDomain = config.repo.secrets.common.services.domains.${serviceName};
lidarrUser = "lidarr";
lidarrGroup = lidarrUser;
lidarrPort = 8686;
@ -18,8 +20,8 @@ let
prowlarrPort = 9696;
in
{
options.swarselsystems.modules.server.transmission = lib.mkEnableOption "enable transmission and friends on server";
config = lib.mkIf config.swarselsystems.modules.server.transmission {
options.swarselsystems.modules.server.${serviceName} = lib.mkEnableOption "enable ${serviceName} and friends on server";
config = lib.mkIf config.swarselsystems.modules.server.${serviceName} {
# this user/group section is probably unneeded
users = {

16
nix/globals-general.nix Normal file
View file

@ -0,0 +1,16 @@
{ lib, ... }:
let
# Try to access the extra builtin we loaded via nix-plugins.
# Throw an error if that doesn't exist.
sopsImportEncrypted =
assert lib.assertMsg (builtins ? extraBuiltins.sopsImportEncrypted)
"The extra builtin 'sopsImportEncrypted' is not available, so repo.secrets cannot be decrypted. Did you forget to add nix-plugins and point it to `./nix/extra-builtins.nix` ?";
builtins.extraBuiltins.sopsImportEncrypted;
in
{
imports = [
(sopsImportEncrypted ../secrets/repo/globals.nix.enc)
];
}

View file

@ -1,10 +1,7 @@
# taken from https://github.com/oddlama/nix-config/blob/main/nix/globals.nix
{ inputs, ... }:
{
flake =
{ config
, lib
, ...
}:
flake = { config, lib, ... }:
{
globals =
let
@ -17,6 +14,7 @@
};
modules = [
../modules/nixos/common/globals.nix
./globals-general.nix
(
{ lib, ... }:
{
@ -39,9 +37,7 @@
inherit (globalsSystem.config.globals)
domains
services
macs
myuser
root
user
;
};
};

View file

@ -31,12 +31,12 @@
paperless = lib.mkDefault true;
transmission = lib.mkDefault true;
syncthing = lib.mkDefault true;
monitoring = lib.mkDefault true;
grafana = lib.mkDefault true;
emacs = lib.mkDefault true;
freshrss = lib.mkDefault true;
jenkins = lib.mkDefault false;
kanidm = lib.mkDefault true;
firefly = lib.mkDefault true;
firefly-iii = lib.mkDefault true;
koillection = lib.mkDefault true;
radicale = lib.mkDefault true;
atuin = lib.mkDefault true;

View file

@ -18,7 +18,7 @@
sops = lib.mkDefault true;
nginx = lib.mkDefault true;
ssh = lib.mkDefault true;
oauth2Proxy = lib.mkDefault true;
oauth2-proxy = lib.mkDefault true;
croc = lib.mkDefault true;
microbin = lib.mkDefault true;
shlink = lib.mkDefault true;

View file

@ -44,6 +44,7 @@
lid = lib.mkDefault true;
lowBattery = lib.mkDefault true;
lanzaboote = lib.mkDefault true;
tmp = lib.mkDefault true;
optional = {
gaming = lib.mkDefault true;

View file

@ -1,4 +1,3 @@
# max. 50 chars is here: #
# <type>[optional scope]: <description>
# types: feat, fix, build, chore, ci, docs, style, refactor, perf, test

View file

@ -0,0 +1,42 @@
{
"data": "ENC[AES256_GCM,data:1h+/I2SLfNqHrqWDAYmkkxFMwbN23zhUVTfWYcG9hmwiZ5KZoGErt1pvR6p2BIyBb3XrfqQoV8TWJrE7IrDKRkdX4MoaviT+W6wXJ46nTJAkJ2lbuNIfQR1paAqiIfeRIzx2GgOf,iv:GIHpghRgq1SBIs8KHzNLTvFJ7aruPd6e4zDe5GjuNo0=,tag:TvXf4qYWoSOqvlqnVsKxsw==,type:str]",
"sops": {
"age": [
{
"recipient": "age1h72072slm2pthn9m2qwjsyy2dsazc6hz97kpzh4gksvv0r2jqecqul8w63",
"enc": "-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBudFBlTlVWMUk4QzByRlN2\nTUcrS0VhV2xEUTc2ZkJjY3dZaTg1ZTBmNVNvCnNhY2FpQkJkQ1VZRDhTN1dUaE5M\nSTJ4WUt0SDA2Y2FSK1JENU5kVkcwNlEKLS0tIFRvV3haejQxNUJUSGd6bkJMa3hM\nVFJQUWNhaGlVenRLSDhHd0VJSDcwKzAKt+JZAK2QVUdB4Nh/xqKS1acqQy7iNMka\n/YrjK6J9CSTGUAjfMZTPXXwstVYaZCZYUnZ0xeIlRZPQw741hx4kWQ==\n-----END AGE ENCRYPTED FILE-----\n"
},
{
"recipient": "age16vzhcvz8tyxj8e0f47fy0z4p3dsg0ak4vl52ut3l07a0tz465cxslmhevl",
"enc": "-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSB2RUM0TVJFam5lTERkSzRZ\nVmF1SmJYU3VlN0psUXlYKzVkV0VNS21UWFNzCjU2b2p3cEZod21rYVNxWDQvS0lB\neHhDTTIySzZ3TnNYTkVQU1g4ejUzOEkKLS0tIDNxaWpMV2RJQzl5T1gyOW1aT0xH\nMFU0S1FyOFZnczhETTBvZkNmQUtvcEEKO32cV09CY6x9ievHyaKNLFR2Jt1y8Pbg\nCXnpvFmXMXROoxRaDN2N4+0SRyjhzuAabyAKszOksW+iJ7fwAmuR/Q==\n-----END AGE ENCRYPTED FILE-----\n"
},
{
"recipient": "age1zlnxraee6tddr07xn59mx5rdexw8qxryd53eqlsajasfhfy78fkq705dfg",
"enc": "-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSAxRFZFcWhDYkpENkhmVzhr\naGVueEFRdUxHZ2l3K24zL1pWR1VtSzUxWWx3CkVReU5FSnI2TDkwV05KaVl6cERY\ndzR2Yk8way9aNlhIZEEwNmUyOTdYYncKLS0tIFNqVHpNczhZREkweCtYWmpPcjdK\nRWdRQ1ZGa256cTJrdEloRmpGTXFDMGsKF9A40XY/cRGd4ZQXnxnlHVxAWks77j+z\nt18W7/lECC0Dt/jLMfEup9dnPyXS60C4Mz35kRNFCPXgvlIiozzyYw==\n-----END AGE ENCRYPTED FILE-----\n"
},
{
"recipient": "age16lnmuuxfuxxtty3atnhut8wseppwnhp7rdhmxqd5tdvs9qnjffjq42sqyy",
"enc": "-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBYdGswSkh5bmZHait6Uisw\nTzRqZDUvOThVWjhHeWFUUGJzUUpWbWU4UkFJCk1pNjZjMUV6UWtHbUc2anpRcmZZ\nYTlOOTJFS2YyS1daRzJMUFZacHJiWjAKLS0tIEcveS9RckRLQ1N4dlRiaGliYW9E\ncmhXeVVnQ3RYSmJKcUs4NTVQLzMvN3cKPxFN6MiGXyXVX0ePLTioLGTxCyEUY+X2\nHJeiFKuFkDIpfdSxrPgwrWY6r8bVeLqMsepdruqUE4o0UGHVEOn7VA==\n-----END AGE ENCRYPTED FILE-----\n"
},
{
"recipient": "age1glge4e97vgqzh332mqs5990vteezu2m8k4wq3z35jk0q8czw3gks2d7a3h",
"enc": "-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSA5S2FWYzNseEkxUndRa2F6\ncW5kYzhvengrZ1pycnphQ2FFR1dYUXh4VlZFCjBPS3FhbXBvanZRNWwyYWZCSmRl\nTEs4V0NaajBkQzRxV2lJalBIVnI2bmMKLS0tIElpV0ZOU0RWWkswZ0Y4UUFiMlN6\neFRGdDIzNHA2b0lGSFFzaFZBcXNsWUkKvpYIHTeGlQ+Bqz/EcjlQ7R6I3yuwNc9l\njQQ99P3tq7bFgj4UIUDdRWaZG7PDGesEJZ6fjJEieA5o5IO3Kq0GAg==\n-----END AGE ENCRYPTED FILE-----\n"
},
{
"recipient": "age18quey88vge7xytclg2nuq4ncme86dg04lxwczqxczmdchnjg3p0saehsnh",
"enc": "-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBibGlMSU4vUEF5UlNVZzlr\nMTMyOFY2Zi8rZFdZT1JrelZEUUZkZHFvOFdzCjVPbVovaU9nZklJQWNZeDJZNm0r\nMXBIK2hsZEY0NElxTVVMWmN6WU1Ld28KLS0tIENaallkK05SMllia3prV25hZDR2\nZDBNU0dYYnJESG1JZGpvSGp1WW9UMVEKJgfdLp7BRXvyAekecNJiaBXmxSj1qNxx\nZeHceqEkfWV/PzX+RP4LHjXTQCLEOJijbKxDmxSsYq49hC9xjZASuw==\n-----END AGE ENCRYPTED FILE-----\n"
}
],
"lastmodified": "2025-07-02T12:24:56Z",
"mac": "ENC[AES256_GCM,data:MTBfNpPWlBI6HbTrcUhydq4NH/4m+kQWPuIjHo2eJmGbdoXk1qN1fHoKTB5U29YZWQuybBiSCRtLLWZdKhs5Vv9UsXOPDsKLflCW+sr0DEKd37ONzhlHhWsHGLF9kFOXZtruJe0p0Sh7oGy3T6ee4ABog3LwQ59ZcRmAxr7haFI=,iv:mDCvJrZXPOeuD01sqoLNGEHcexHZkZ3ankBk/lCMbUs=,tag:fqqJ8O8lI30SIqcCxAXVPA==,type:str]",
"pgp": [
{
"created_at": "2025-07-02T12:10:18Z",
"enc": "-----BEGIN PGP MESSAGE-----\n\nhQIMAwDh3VI7VctTAQ//YG1H7a2MZEWjFupRqe1jgxJMsDXq0zWdK8Wy9mHCLmEk\njFJL8xjuJGYx1tKlQKq5tLPob1NmnIr9KXwtarFrIdWY34BwqmkYSO8Vmcp7iq5U\nL0xTRX4ZWTyOpTMwsIhIrEGWd1be4HlS/QedJxOn7/D5Y+XBHf+0t+4ScE+4n4ek\nlRhSxR9OlFrmmxAjD/PHsrekgi7wX02lHhy+yKmDQ4YYL3ve6AONY3dltOFr1wk3\nQ3ffjIGegkXTiafNbAvo6joekDDIGm44lRCoaxuS/0ZbDC0IZN9EUpw7KmJvRpaW\nkYWKLLZn07CpsG5cNvZvcSMTyVi+La7WJ4Nf8x+6XzRboVcVfQ/ZnCFqUKJTIGcS\ni+UBMgNxX7PCVmbQ2pIKzn5eSk0OTwgUv4LOJzivFDc60Mk/iq2c8ptOOuzBxhR2\n/M1fs4D8QfseU3b+/2e1ysVZGpba/QxYkdgeAa3FtZz8YpgFlSHdenuljrJke28I\nqkwWEdR80jBXwZ785Ur7Uqw3Pjv0xW9hwa0s3yJ1HyL4Was0ONp2aJIW1NSRbbFv\njTVJVQOJVz+bxMla9t9cB6JmV/JxSe4Q7dkiHFxdmxug2qL9aqpXFRy0M+R6HClp\n8FjvClOhyRAOFYwjm4Ry/jY1mM33hh+KiJ9fYxAZ6ZQBonl3BdOq6/LbAwKDdC6F\nAgwDC9FRLmchgYQBD/9YHAFQvEDfzbTbJrQT4BjqRyKjgA27tA3D8MwS9Gvub91V\nJfaYbn0bc9oJBqkTEmiKw2zOTTbEC0zw18aB3rHrAc0EjYZCP9XMYQvctJo1XAKo\nZFJcCCmdKzLX6XO7rLOyjEp4J5QfdgR2NAt4NXbBH9SjqNJ29bQhR14JyYUtd+Wo\nHcypltxgX4Hd69ZHBrhY/1YVfhLOoO/vhiyCLZPFrV5HYGo7Dzrtw1aZg+RYAH5R\nixZ+ADpdVj1Tc0EwBEIzjsmJ28g8liYOeRI8g4X8/RmgJRtPerBRMxXqXxHHU0Bq\ngZpm4Aafy2NGLWPQjjjbWO3emQSkQWPtldyiYf2pSdixm8gahMK4/As3Ziu1MvIw\nMlu6TsOca2762DJfw3eWJ7DeVAVH0gDOeibPMlRVOIlqRbKOg58ZDsVMwyQaiTxC\nWa/2Do6jOIEfWGhM8MbzVuhqEvkxlUHDJjP2v50SPCBVhdI3p+im5mr9cgalwlp/\nanSR7KMC1diRz2cpePb3bHgtJGoSHRoId85Xo/mhgPQS3wJGujEUafQQRR089YF7\nLHWgahHAYX1RP0tYA9sJQxBZkc4ryCMk3R6k6HdiZsoGB5D5rJa4ufdACrgsCuML\noF/hCCulldltYNN9ZekgB1Xii5SEYku0NP4NZnA6dsoXDE7hlcy95bm09iA7StJe\nASuM1tJbFJI7eRKdg2OafM5+aVGRsJqHmYue9sD+LY7LoOK0nR6tPrL97AybKqq1\nsHwXmxhaJglwBpConTHTIIKQw0ZGUuzowFHjrTs69lLkdIOq3BP8/3cBYJAeLw==\n=P5FL\n-----END PGP MESSAGE-----",
"fp": "4BE7925262289B476DBBC17B76FD3810215AE097"
}
],
"unencrypted_suffix": "_unencrypted",
"version": "3.10.2"
}
}

View file

@ -1,5 +1,5 @@
{
"data": "ENC[AES256_GCM,data:K6Exxoz4dyUuVSvS0BQOyjCQ7iuicPUJbDYhWtX350/9tOhu9XorVNmI1ezfFEmY8iAdxVy/E3QEEQcO+XjJVEVGKoX8NtAWSMUkRJT/S2MLG0nNt3kcsIhoya3S5SDiblMIA+S/yFJOmsyykgLUynYgR9QL5URdGj2utoSi9+WYvUsbxrlmcxIqk443huoq4AeZp5X+HVSIhq0rby0/Uc62ox6jz4S9CwSNTOc41xI6UNRz96xppqcAhru7NjZxomtbI9LaDBMVVRe+k5GrKCTyjqp7JCaeN19Sba/k7Uh+4VOVokNEEL0cYNIZXh8eBBxT3ogQhAfOZXfp+lWKf1bAZvVFBrXI4cSGjNUDcbYCIa1gv+rdaVMju29ZNBp+Hx9p4WjJz6zFAbC+tjmH6wBjGNz8Zeqn5Mmm755yPgdvsVAW4ZZfB49T6qOjkDnNSltoHw0n49qTVS7AmQRSQvzPERyAte3IyftQ0bIGALE27h5oB6ls7X9EXUPyNqaT1G0trnrq5D8L4C3xqYJB3KriHA7PNfpKyOVM50ryACyuF2QRHeWfBnFu78hQbMg4lWYXnVggZQdeFDaHZUeYpJCmeyehmSl88+v8f6hjV0aDPlYh8Yv7lfJokGyffMNq0ShmT2/FBPu+9iAvk/apcE8KFdlct5qtkRaOeXp2iwnHWr2bYg/JQ4D4/xePvqBfV22Qd2MarA1qW7ggVJNCbKcOSJzwbEjPGjBjkH6crfO4LD/SYmVMgSoSGojdyLc7hsAFoUtdhzfknV6vVF7h0TTIIEVIEYt0HJGIfMk3PQ4Z+4O7PSwZXxctT8d7GvuWA45QMO+Ok3pRxqNmWUxEHrJF75l+lZMnSrtjdR1r+vNPnwJxHOgn/2h0sYYvqGVVZdHapxdi+V6za0f/,iv:xXAjuNpqXRuReAH6dlunrbPgspj2/+VtCV3p+xjtOi0=,tag:m//iBHvmYmWw4vtgojbpFw==,type:str]",
"data": "ENC[AES256_GCM,data:7dWpQIRuyPRNk/fZH9nI3KgDPK8LcydFUrk8bpgK3454O1VkNGUkGnRuVfPRuBdXydMXphjB4BE8XLZGmrxS5GbvUUcxYmSGmgNqlYSLZBhcHoxnOlnAubckvst2Twf5ORBienNEo4x+9JjpGKhYXfYvULww8gM5N5mJN0qwqWOCrSgk7fYDGHUtJ187RqBlO6zQFSxT69fMUGSyzqpLahvZeqb0VaZ/aG0XpzgIeFkOFj7FkfSoA1JkY5ls+QIamvpBTib2yHh8kmDV2WIrQCEgLtbPCJxV8/9CZbhR/COUL1QjoQs5012XdyPzw5/3xOytEGmQc5Qhjd35JnnfKDyecYkb/nO2t2xpmklh1uNgy3CywzxnBj+K2aD8iRum6gVMH5xTwX/qs+ctz6bHnTy1fJp75kWMBDV4WErOz/5N3dzpRd3mZU4juQXbZC0ND1N/sx5U+IIusnASs5unkV5/FY0H6FLRwiV7kY6UCo72XAzQxr8FCrPrV+ElKaT+EGdeMi8voyssp8iYh+UYsd/6M5vH0prCGhHZ+6H/IPf1brehf2MLbK1GdmVcIGb+i0wzCqa3bOMkDKyPX0WXJYGcJZn6O+WeFbiv5XhaWxHm2ML13HDxWo1RHpIlYVw+n0vGgZcWPxE3YLjKzurKVoJ+ELQD8I3HTDSRC4Yr8xa/61LIv+Cr4LSs9YVAfuNdaH6ZgFPXFw4F3zG7M0vzi2jl2jFz/AGbXaOQQIn0GygPJ48F7R6CsyoK9sc2l5stZXEVf9Hj9mZV/K6xpLYIckkFLnXGBz4c6F7WwN71wrz6r2mMexCUrPscu1qiSrVURMIv5v3e6UgR/p/Kzt3LphP6pEckI1jxK4Ed/iynXVMrxWrcG+5iS+hgI7F7D+7I6SAU6vI5NnBC4DpOpSSxIehClbgpFVEyeWJIezAMCpMPfF6EkDm83fQ8NMtc3qL0rfp3ESyFZtC0kK4HjIizAPcSVthfF9qIggTxVgOCPRE+GcM8agjzI20JuJaWQ42K9Cg+2u5uNZE1ZCNoXEV0lCory5h1iD4NjT9POSb6ds7k9x/rFB4n1CB8CpnzEeKwHW1jaknGFvekrQPcUsVIDvIdxbdixqolFb5nbPZ/NBX0X3zJmoRAAO8Q6B9ywXTVYDIrAQuYoHuWQr+UM75DYaK/e/bG9K6zelaq0drg7RYA+HncvFemm/4aPGehYHn1GnCZ6Par8oGsXBzk2ux4w8jwl0P7XEQZ3n9ej0rSG07v+cci3yY7mjAyYbcmHW4CDFdryibrMNIk9z9YJwrsaT4aMWHIXXiLqBcDwTJxTbT9mCjm5OSZ4KqDQYXLR2p0sjtXrKndjxOVzlqZ3BzE3zAQQfP80BygKlwZORz/cvR35vYyMe5C45MUl31B2fGpsX33LeLk3WrkWQv72BY23og6hKoNAPSCJupmAbWkmsDNwihsDwqx3ABbVH7rWYsii+VaTLC7drG6FtW1TJELBLtsRLCmPyivVrWbrK6ENj9N8h7UOcSZpd2TWCG/SeAeetvtc5mi79Ok1jRhVtDNF+lsI6FKzT5F0Nqjcr1QRoKyQYXoBIFgDrYJuw0pef2Fxpn2OprJd43PaeUzwBdKrTRMl6xg9T2YdNDVK+Y0IjDWh5vN590ti7K855tqgoYo2/3rwgsp6a3AvyITrYortG6iCmNkMRIc1szrViYTvC890+cdUUNw5VqrefF5zrbF9tyzV8yTKW8tWuchLMr2GQ4ZNzHT5Y2vE5U3bakZrDVf6LpQYI1W5HZ5zxOHhQzQpvSjaHHY5ViDtzvH3vE7dfgeWBm5GO8P7xIzK7eN11jHcVhtDXBnsDIkclO+vPIiY18kE0+F3HLJKLLRXTPUqvgqMf19gA4zqiaJI11PpoxtdH3AHyzN7Kj0jBXGDG4F5cl3myJ1QrXv3d5YK0TpEse4Tlg+LnKxZGU8ePJru91T2tmgRb7Y6dy+VTKi+r1lMHkV2v199Oz6nfFUyc7GzcHhvM8024slpcHNi22ZpelyTWtEzWWHE/Tj1pqZDOOt/b3mbYTlfcLDY2s/agWsY2Pv00ZoV8+pYEv7r83Yv3uixibxT+CHM8M1NzIGgAXdOCrIRSJapQeGqppUJj42QS/WBQ==,iv:y6HKnzcG5fd+muvJ06NAF6IRR6MHzEP0Nfuk5SiLung=,tag:26txIqAHo5p8XEswWtJP3w==,type:str]",
"sops": {
"age": [
{
@ -27,8 +27,8 @@
"enc": "-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBtU240VjVRZmJ5TGsrclJF\nRXRLbTRCZURtR0Z3d2E2eDNNeGRDODlXVEY4CllTeVFYbDJQWlRSS1RFLzAxSnlM\nZi9NU1c3cWo3YWRLcUJ2U2ZFWFBBVEEKLS0tIGtmZU9qSWdBT3RDeStaaFFDSWtk\ndkUzZXJwZUl4LzVxYXdidmxXRnNnclUKyAMZqCKSY/RQvTR4bbjLaPnGKwdBcHXc\nvtiVSrLdIdzMa6id/J07TJH5UesUmcp0wjU41MDa4aMBLy+cXhuBHA==\n-----END AGE ENCRYPTED FILE-----\n"
}
],
"lastmodified": "2025-07-01T10:27:51Z",
"mac": "ENC[AES256_GCM,data:RyksomYlwuQTcCfmZqmxMMoanvIzu4FcJ+xlUjbBu9Kb/OU5cp8PJXdA78jY/58GOu9s3fkSD1wFewFrPTwtO8xry4Fvw8smr2wttvDS4c6nJ/9lg3Vab147JCEszqHLxghGV48tChvB2zfhpVy1LoF4y+vixMPIrlTFAw+ICzg=,iv:0LzxSmi8kCweETwQw9+UDpudZvJiTaT9UMLfmi990gQ=,tag:vl2y2f3G+Xn1fWwgkE7NfQ==,type:str]",
"lastmodified": "2025-07-02T12:38:20Z",
"mac": "ENC[AES256_GCM,data:BWXYSlrqB28us/6YghcLBkbC+HVCS9KTmnkutff4fhenldjqJkUXTDgHIyHmibeTE8bbuuypCi1xWlEykbQ0msYoz9X6MAe9MsE1HjcWUudLNNrZ8ae1Cs/vRLZfIgigwmLDkas9VL+5sTFnEpdiPbQ4Ov5GOtRUPm6HKTj9l9U=,iv:Z5dIjU0tz+efSjES7L/gIiwKHy53Xtb9K8huBmBwOag=,tag:IhVCdtC/3EdO+FRjCJKboQ==,type:str]",
"pgp": [
{
"created_at": "2025-06-13T20:13:06Z",

View file

@ -79,8 +79,8 @@ sops:
MEZ1UWw3alF1WnJZMFZvMFBpbDFJZlUKGRnoEEgjgJ9SSblmldtY6d8MdAy01yxl
qkvEIoXbL+ky2ira7EgjD0legThzCnmlXUlcSn3SpwbkAGgcfd2kWA==
-----END AGE ENCRYPTED FILE-----
lastmodified: "2025-06-28T23:22:53Z"
mac: ENC[AES256_GCM,data:qzxBlSs1thae4TAtkyLkR5l+vMZT/gB6q/NbrdRpv3jPKpn7JL/LLDXX4DjPuZJjDt3T95s9ZBzpasuGHwVNNesdtfj4wjepzwppsgxecSILmiqTUjZC6p1GnMp4TugeLoFBv5qjPYpmu67kwAO8R+gKn/hDhXeIWI4MjgVqsGg=,iv:Gk4vaDOM/lORN5ug96WncFQx972r+LHWTZeLE8Qh6wA=,tag:pSH6xAXJIAtr1bvBMsQ7QA==,type:str]
lastmodified: "2025-07-01T23:25:43Z"
mac: ENC[AES256_GCM,data:TS1UWyZGQ1zgzHGVlcWhWgWgo56zaSbhcB3KryS6Ya5clgyFt4vY0R4dC+uYnjmY1QCXAFPVLQU24ufKFDz94fEm0sQCPEWF2d1n156IpMce4wtCUqc0sXJOqTI3OA8ty91EWSUXTaapXEG2Pd9MSKr6XXpAVVbhzXKU1rFd1zc=,iv:xeOThqJ0tWUu55O8JAQMi0D6YzkrrHe7AshSATgpQ2U=,tag:VvtzsK1/06BD39bfQUr7Mg==,type:str]
pgp:
- created_at: "2024-12-17T16:24:32Z"
enc: |-

View file

@ -1,5 +1,7 @@
#ENC[AES256_GCM,data:K3S1LFrPmaS5,iv:dxFzPLhN2otgy02VWzrLURmomtYdoIBHvEJ1LJ7Lj9k=,tag:stKgkBnRDZkCPlvFk+btRg==,type:comment]
radicale-user: ENC[AES256_GCM,data:2G+WXxw6jrnPXsI=,iv:bUEhBDrdTt+O/4TXMkhmqnzfkSiws4n7L54Z0zZnSOI=,tag:JGQPit5uGqITUyyCpU3OIg==,type:str]
#ENC[AES256_GCM,data:+7JEI2P/6/5yiWQ=,iv:hV4TyNFsyugrfFM0emxGDDDq54XWy7fVCf/kwD0mtCM=,tag:iZz9mPsLG02rlgV1vP8aBQ==,type:comment]
prometheus-admin-hash: ENC[AES256_GCM,data:dUmTW6W419TzF8dLGcgRLlbLBg9puzgznNCrrAuNOIuhXCBrqaJdtyIVFCsnrDSEh1ZdMfGki4UERZcf,iv:XIlb65V6yhrKSU7AbRs6k1ISljZjWnAm1dPTCONwDJI=,tag:UkdDTywivitSxYR902uM5A==,type:str]
sops:
age:
- recipient: age1h72072slm2pthn9m2qwjsyy2dsazc6hz97kpzh4gksvv0r2jqecqul8w63
@ -11,8 +13,8 @@ sops:
ZWxwbGs1bTNzdXVNSzhpNWVESGJlUzQKzZr3cYBF6s5ihgW/6CreOKWvQpqITrFX
pW6gwbRbxaxDPRRdfn8qswcezxq5AwOk9drbOH+qgcwL2owRGxEhcQ==
-----END AGE ENCRYPTED FILE-----
lastmodified: "2025-06-28T23:22:45Z"
mac: ENC[AES256_GCM,data:gfvgF71vpP2NWy8GEYDffy6ZEI4xq2Pb+ydlmhAxuVtkVveVc3xOzJH+/IJ4IOh8s2ik/b5KMP1u2OdU7gZzDbAQvMn6t+1NN6wun2TLTMCf/z1KuJYEddYS1KHtKmyj+CS7cEZtaW5EKDrATZ9WJOlLY0IADIPicO6kwIqGQew=,iv:1Cg7Mp6GXL6Ade4KfZoHETYNNKojheQHNOlJh2+BCGg=,tag:CvLNFSAkiJDrLMYUldn36Q==,type:str]
lastmodified: "2025-07-01T23:26:55Z"
mac: ENC[AES256_GCM,data:YQtQicQAfEeB404BTZCZg7SSzVEw4ezlHw0ISoOHeOEBmlhS5441Mv6HrTWr47K+/aKvzcSdyl4dKclUzlgPoggWdJy7QHvFl4sm+iMuLP+3tAjLVJIudai/BAPNC4uFWEEXVUdlryPE/lX/I5ddCUoI2YfQV2gY2PlKXd2+cjs=,iv:PT3ZYJV/Kqet38FGrmG3jPNTkTYw2SJv0gwJGU4xP1A=,tag:gHdn6yojkAkusTumGMydlg==,type:str]
pgp:
- created_at: "2025-06-28T23:22:37Z"
enc: |-

View file

@ -1,5 +1,4 @@
# based on https://github.com/pyproject-nix/uv2nix/tree/master/templates/hello-world
{
description = "Python flake using uv2nix";

View file

@ -53,7 +53,7 @@ in
]
[ "wan" ]
];
interfaces.wg0 = {
interfaces.wg = {
addresses = [ "192.168.3.1" ];
network = "wg";
virtual = true;

Binary file not shown.

After

Width:  |  Height:  |  Size: 91 KiB