diff --git a/SwarselSystems.org b/SwarselSystems.org index 7cb75f8..77185f7 100644 --- a/SwarselSystems.org +++ b/SwarselSystems.org @@ -1623,16 +1623,6 @@ This machine mainly acts as an external sync helper. It manages the following th devices = [ "winters" "magicant" "${workHostName}" ]; id = "hgp9s-fyq3p"; }; - ".elfeed" = { - path = "/sync/elfeed"; - type = "receiveonly"; - versioning = { - type = "simple"; - params.keep = "5"; - }; - devices = [ "winters" ]; - id = "h7xbs-fs9v1"; - }; "Documents" = { path = "/sync/Documents"; type = "receiveonly"; @@ -4685,6 +4675,7 @@ Modules that need to be loaded on the NixOS level. Note that these will not be a navidrome = lib.mkDefault true; spotifyd = lib.mkDefault true; mpd = lib.mkDefault true; + postgresql = lib.mkDefault true; matrix = lib.mkDefault true; nextcloud = lib.mkDefault true; immich = lib.mkDefault true; @@ -7722,8 +7713,6 @@ Here we just define some aliases for rebuilding the system, and we allow some in lego ]; - # users.users.acme = {}; - sops = { # secrets.dnstokenfull = { owner = "acme"; }; secrets.dnstokenfull = { }; @@ -7836,6 +7825,7 @@ Here I am forcing =startWhenNeeded= to false so that the value will not be set t user = serviceUser; settings.Port = servicePort; tokenKeyFile = config.sops.secrets.kavita.path; + dataDir = "/Vault/data/kavita"; }; nodes.moonside.services.nginx = { @@ -7960,7 +7950,7 @@ Here I am forcing =startWhenNeeded= to false so that the value will not be set t users = { groups = { - "$(serviceGroup}" = { + "${serviceGroup}" = { gid = 61593; }; }; @@ -7990,6 +7980,7 @@ Here I am forcing =startWhenNeeded= to false so that the value will not be set t Port = servicePort; MusicFolder = "/Vault/Eternor/Music"; PlaylistsPath = "./Playlists"; + AutoImportPlaylists = false; EnableSharing = true; EnableTranscodingConfig = true; Scanner.GroupAlbumReleases = true; @@ -8016,6 +8007,7 @@ Here I am forcing =startWhenNeeded= to false so that the value will not be set t }; UILoginBackgroundUrl = "https://i.imgur.com/OMLxi7l.png"; UIWelcomeMessage = "~SwarselSound~"; + EnableInsightsCollector = false; }; }; @@ -8218,13 +8210,35 @@ Here I am forcing =startWhenNeeded= to false so that the value will not be set t } #+end_src +**** postgresql + +#+begin_src nix :tangle modules/nixos/server/postgresql.nix + { config, lib, pkgs, ... }: + let + serviceName = "postgresql"; + postgresVersion = 14; + in + { + options.swarselsystems.modules.server."${serviceName}" = lib.mkEnableOption "enable ${serviceName} on server"; + config = lib.mkIf config.swarselsystems.modules.server."${serviceName}" { + services = { + postgresql = { + enable = true; + package = pkgs."postgresql_${builtins.toString postgresVersion}"; + dataDir = "/Vault/data/postgresql/${builtins.toString postgresVersion}"; + }; + }; + }; + } +#+end_src + **** matrix :PROPERTIES: :CUSTOM_ID: h:1e68d84a-8f99-422f-89ac-78f664ac0013 :END: #+begin_src nix :tangle modules/nixos/server/matrix.nix - { config, lib, pkgs, sops, ... }: + { lib, config, pkgs, ... }: let matrixDomain = "swatrix.swarsel.win"; serviceName = "matrix"; @@ -8342,12 +8356,16 @@ Here I am forcing =startWhenNeeded= to false so that the value will not be set t matrix-synapse = { enable = true; + dataDir = "/Vault/data/matrix-synapse"; settings = { - app_service_config_files = [ - "/var/lib/matrix-synapse/telegram-registration.yaml" - "/var/lib/matrix-synapse/whatsapp-registration.yaml" - "/var/lib/matrix-synapse/signal-registration.yaml" - "/var/lib/matrix-synapse/doublepuppet.yaml" + app_service_config_files = let + inherit (config.services.matrix-synapse) dataDir; + in + [ + "${dataDir}/telegram-registration.yaml" + "${dataDir}/whatsapp-registration.yaml" + "${dataDir}/signal-registration.yaml" + "${dataDir}/doublepuppet.yaml" ]; server_name = matrixDomain; public_baseurl = "https://${matrixDomain}"; @@ -8602,7 +8620,7 @@ Here I am forcing =startWhenNeeded= to false so that the value will not be set t }; package = pkgs.nextcloud31; hostName = serviceDomain; - home = "/Vault/apps/nextcloud"; + home = "/Vault/data/nextcloud"; datadir = "/Vault/data/nextcloud"; https = true; configureRedis = true; @@ -8672,7 +8690,7 @@ Here I am forcing =startWhenNeeded= to false so that the value will not be set t host = "0.0.0.0"; port = servicePort; openFirewall = true; - mediaLocation = "/Vault/Eternor/Immich"; + mediaLocation = "/Vault/Eternor/Immich"; # dataDir environment = { IMMICH_MACHINE_LEARNING_URL = lib.mkForce "http://localhost:3003"; }; @@ -8866,6 +8884,21 @@ Also I install Tika and Gotenberg, which are needed to create PDFs out of =.eml= { self, pkgs, lib, config, ... }: let serviceDomain = "store.swarsel.win"; + lidarrUser = "lidarr"; + lidarrGroup = lidarrUser; + lidarrPort = 8686; + radarrUser = "radarr"; + radarrGroup = radarrUser; + radarrPort = 7878; + sonarrUser = "sonarr"; + sonarrGroup = sonarrUser; + sonarrPort = 8989; + readarrUser = "readarr"; + readarrGroup = readarrUser; + readarrPort = 8787; + prowlarrUser = "prowlarr"; + prowlarrGroup = prowlarrUser; + prowlarrPort = 9696; in { options.swarselsystems.modules.server.transmission = lib.mkEnableOption "enable transmission and friends on server"; @@ -8877,11 +8910,11 @@ Also I install Tika and Gotenberg, which are needed to create PDFs out of =.eml= dockeruser = { gid = 1155; }; - radarr = { }; - readarr = { }; - sonarr = { }; - lidarr = { }; - prowlarr = { }; + "${radarrGroup}" = { }; + "${readarrGroup}" = { }; + "${sonarrGroup}" = { }; + "${lidarrGroup}" = { }; + "${prowlarrGroup}" = { }; }; users = { dockeruser = { @@ -8890,29 +8923,29 @@ Also I install Tika and Gotenberg, which are needed to create PDFs out of =.eml= group = "docker"; extraGroups = [ "users" ]; }; - radarr = { + "${radarrUser}" = { isSystemUser = true; - group = "radarr"; + group = radarrGroup; extraGroups = [ "users" ]; }; - readarr = { + "${readarrGroup}" = { isSystemUser = true; - group = "readarr"; + group = readarrGroup; extraGroups = [ "users" ]; }; - sonarr = { + "${sonarrGroup}" = { isSystemUser = true; - group = "sonarr"; + group = sonarrGroup; extraGroups = [ "users" ]; }; - lidarr = { + "${lidarrUser}" = { isSystemUser = true; - group = "lidarr"; + group = lidarrGroup; extraGroups = [ "users" ]; }; - prowlarr = { + "${prowlarrGroup}" = { isSystemUser = true; - group = "prowlarr"; + group = prowlarrGroup; extraGroups = [ "users" ]; }; }; @@ -8938,32 +8971,45 @@ Also I install Tika and Gotenberg, which are needed to create PDFs out of =.eml= services = { radarr = { enable = true; + user = radarrUser; + group = radarrGroup; + settings.server.port = radarrPort; openFirewall = true; - dataDir = "/Vault/apps/radarr"; + dataDir = "/Vault/data/radarr"; }; readarr = { enable = true; + user = readarrUser; + group = readarrGroup; + settings.server.port = readarrPort; openFirewall = true; - dataDir = "/Vault/apps/readarr"; + dataDir = "/Vault/data/readarr"; }; sonarr = { enable = true; + user = sonarrUser; + group = sonarrGroup; + settings.server.port = sonarrPort; openFirewall = true; - dataDir = "/Vault/apps/sonarr"; + dataDir = "/Vault/data/sonarr"; }; lidarr = { enable = true; + user = lidarrUser; + group = lidarrGroup; + settings.server.port = lidarrPort; openFirewall = true; - dataDir = "/Vault/apps/lidarr"; + dataDir = "/Vault/data/lidarr"; }; prowlarr = { enable = true; + settings.server.port = prowlarrPort; openFirewall = true; }; nginx = { virtualHosts = { - "store.swarsel.win" = { + "${serviceDomain}" = { enableACME = false; forceSSL = false; acmeRoot = null; @@ -8975,31 +9021,31 @@ Also I install Tika and Gotenberg, which are needed to create PDFs out of =.eml= ''; }; "/radarr" = { - proxyPass = "http://localhost:7878"; + proxyPass = "http://localhost:${builtins.toString radarrPort}"; extraConfig = '' client_max_body_size 0; ''; }; "/readarr" = { - proxyPass = "http://localhost:8787"; + proxyPass = "http://localhost:${builtins.toString readarrPort}"; extraConfig = '' client_max_body_size 0; ''; }; "/sonarr" = { - proxyPass = "http://localhost:8989"; + proxyPass = "http://localhost:${builtins.toString sonarrPort}"; extraConfig = '' client_max_body_size 0; ''; }; "/lidarr" = { - proxyPass = "http://localhost:8686"; + proxyPass = "http://localhost:${builtins.toString lidarrPort}"; extraConfig = '' client_max_body_size 0; ''; }; "/prowlarr" = { - proxyPass = "http://localhost:9696"; + proxyPass = "http://localhost:${builtins.toString prowlarrPort}"; extraConfig = '' client_max_body_size 0; ''; @@ -9048,7 +9094,7 @@ Also I install Tika and Gotenberg, which are needed to create PDFs out of =.eml= user = serviceUser; group = serviceGroup; dataDir = "/Vault/data/syncthing"; - configDir = "/Vault/apps/syncthing"; + configDir = "/Vault/data/syncthing/.config/syncthing"; guiAddress = "0.0.0.0:${builtins.toString servicePort}"; openDefaultPorts = true; # opens ports TCP/UDP 22000 and UDP 21027 for discovery relay.enable = false; @@ -9106,16 +9152,16 @@ Also I install Tika and Gotenberg, which are needed to create PDFs out of =.eml= devices = [ "sync (@oracle)" "magicant" "${workHostName}" "moonside (@oracle)" ]; id = "hgp9s-fyq3p"; }; - "Documents" = { - path = "/Vault/data/syncthing/Documents"; - type = "receiveonly"; - versioning = { - type = "simple"; - params.keep = "5"; - }; - devices = [ "magicant" "${workHostName}" "moonside (@oracle)" ]; - id = "hgr3d-pfu3w"; - }; + # "Documents" = { + # path = "/Vault/data/syncthing/Documents"; + # type = "receiveonly"; + # versioning = { + # type = "simple"; + # params.keep = "5"; + # }; + # devices = [ "magicant" "${workHostName}" "moonside (@oracle)" ]; + # id = "hgr3d-pfu3w"; + # }; }; }; }; @@ -9188,7 +9234,6 @@ This manages backups for my pictures and obsidian files. "/Vault/Eternor/Paperless" "/Vault/Eternor/Bilder" "/Vault/Eternor/Immich" - "/Vault/familymedia" ]; pruneOpts = [ "--keep-daily 3" diff --git a/hosts/nixos/moonside/default.nix b/hosts/nixos/moonside/default.nix index 0a49c9c..dd7a28f 100644 --- a/hosts/nixos/moonside/default.nix +++ b/hosts/nixos/moonside/default.nix @@ -167,16 +167,6 @@ in devices = [ "winters" "magicant" "${workHostName}" ]; id = "hgp9s-fyq3p"; }; - ".elfeed" = { - path = "/sync/elfeed"; - type = "receiveonly"; - versioning = { - type = "simple"; - params.keep = "5"; - }; - devices = [ "winters" ]; - id = "h7xbs-fs9v1"; - }; "Documents" = { path = "/sync/Documents"; type = "receiveonly"; diff --git a/index.html b/index.html index 057b9da..7587754 100644 --- a/index.html +++ b/index.html @@ -3,7 +3,7 @@ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
- +-This file has 69596 words spanning 18782 lines and was last revised on 2025-06-16 00:41:03 +0200. +This file has 69694 words spanning 18853 lines and was last revised on 2025-06-16 23:03:27 +0200.
@@ -785,7 +786,7 @@ This section defines my Emacs configuration. For a while, I considered to use ry
-My emacs is built using the emacs-overlay nix flake, which builds a bleeding edge emacs on wayland (pgtk) with utilities like treesitter support. By executing the below source block, the current build setting can be updated at any time, and you can see my most up-to-date build options (last updated: 2025-06-16 00:41:03 +0200) +My emacs is built using the emacs-overlay nix flake, which builds a bleeding edge emacs on wayland (pgtk) with utilities like treesitter support. By executing the below source block, the current build setting can be updated at any time, and you can see my most up-to-date build options (last updated: 2025-06-16 23:03:27 +0200)
@@ -1821,6 +1822,7 @@ in swarselsystems = lib.recursiveUpdate { + info = "Framework Laptop 16, 7940HS, RX7700S, 64GB RAM"; firewall = lib.mkForce true; wallpaper = self + /wallpaper/lenovowp.png; hasBluetooth = true; @@ -1844,7 +1846,6 @@ in # home.stateVersion = lib.mkForce "23.05"; swarselsystems = lib.recursiveUpdate { - info = "Framework Laptop 16, 7940HS, RX7700S, 64GB RAM"; isLaptop = true; isNixos = true; isSecondaryGpu = true; @@ -2461,12 +2462,12 @@ in -{ lib, config, primaryUser, ... }:
@@ -2638,16 +2639,6 @@ in
devices = [ "winters" "magicant" "${workHostName}" ];
id = "hgp9s-fyq3p";
};
- ".elfeed" = {
- path = "/sync/elfeed";
- type = "receiveonly";
- versioning = {
- type = "simple";
- params.keep = "5";
- };
- devices = [ "winters" ];
- id = "h7xbs-fs9v1";
- };
"Documents" = {
path = "/sync/Documents";
type = "receiveonly";
@@ -2711,8 +2702,8 @@ in
loader.grub = {
@@ -3355,8 +3346,8 @@ This is just a demo host. It applies all the configuration found in the common p
I also set the WLR_RENDERER_ALLOW_SOFTWARE=1 to allow this configuration to run in a virtualized environment. I also enable qemuGuest for a smoother experience when testing on QEMU.
{ self, inputs, config, pkgs, lib, primaryUser, ... }:
@@ -3435,8 +3426,8 @@ in
_: @@ -3446,8 +3437,8 @@ in
_:
@@ -5228,8 +5219,8 @@ appimageTools.wrapType2 {
# heavily inspired from https://github.com/oddlama/nix-config/blob/d42cbde676001a7ad8a3cace156e050933a4dcc3/pkgs/deploy.nix
@@ -5360,8 +5351,8 @@ writeShellApplication {
This programs simply runs ssh-keygen on the last host that I tried to ssh into. I need this frequently when working with cloud-init usually. @@ -5518,8 +5509,8 @@ in
{ lib, config, ... }:
@@ -5589,8 +5580,8 @@ in
{ lib, config, ... }:
@@ -5652,8 +5643,8 @@ in
{ lib, config, ... }:
@@ -5685,8 +5676,8 @@ in
{ lib, config, ... }:
@@ -5707,8 +5698,8 @@ in
{ lib, config, ... }:
@@ -5729,8 +5720,8 @@ in
{ lib, config, ... }:
@@ -5751,8 +5742,8 @@ in
{ lib, config, ... }:
@@ -5773,8 +5764,8 @@ in
{ lib, config, ... }:
@@ -5795,8 +5786,8 @@ in
{ lib, config, ... }:
@@ -5817,8 +5808,8 @@ in
{ lib, config, ... }:
@@ -5847,6 +5838,7 @@ in
navidrome = lib.mkDefault true;
spotifyd = lib.mkDefault true;
mpd = lib.mkDefault true;
+ postgresql = lib.mkDefault true;
matrix = lib.mkDefault true;
nextcloud = lib.mkDefault true;
immich = lib.mkDefault true;
@@ -5871,8 +5863,8 @@ in
{ lib, config, ... }:
@@ -5908,8 +5900,8 @@ in
{ lib, config, ... }:
@@ -5963,8 +5955,8 @@ in
{ lib, config, ... }:
@@ -6021,8 +6013,8 @@ in
{ lib, config, ... }:
@@ -6074,8 +6066,8 @@ in
{ lib, config, ... }:
@@ -6095,8 +6087,8 @@ in
{ lib, config, ... }:
@@ -6116,8 +6108,8 @@ in
{ lib, config, ... }:
@@ -6138,8 +6130,8 @@ in
{ lib, config, ... }:
@@ -6157,8 +6149,8 @@ in
{ lib, config, ... }:
@@ -6405,12 +6397,12 @@ in
@@ -6445,8 +6437,8 @@ in
#!/usr/bin/env bash @@ -6493,8 +6485,8 @@ fi
{ config, ... }:
@@ -6878,8 +6870,8 @@ A breakdown of the flags being set:
{ config, lib, outputs, ... }:
@@ -7679,8 +7671,8 @@ Setup timezone and locale. I want to use the US layout, but have the rest adapte
{ lib, ... }:
@@ -7703,8 +7695,8 @@ Setup timezone and locale. I want to use the US layout, but have the rest adapte
{ self, lib, config, ... }:
@@ -7798,8 +7790,8 @@ in
{ config, inputs, lib, ... }:
@@ -8194,8 +8186,8 @@ Most of the time I am using power-saver, however, it is good to be
{ lib, pkgs, config, ... }:
@@ -9087,8 +9079,6 @@ in
lego
];
- # users.users.acme = {};
-
sops = {
# secrets.dnstokenfull = { owner = "acme"; };
secrets.dnstokenfull = { };
@@ -9203,6 +9193,7 @@ in
user = serviceUser;
settings.Port = servicePort;
tokenKeyFile = config.sops.secrets.kavita.path;
+ dataDir = "/Vault/data/kavita";
};
nodes.moonside.services.nginx = {
@@ -9327,7 +9318,7 @@ in
users = {
groups = {
- "$(serviceGroup}" = {
+ "${serviceGroup}" = {
gid = 61593;
};
};
@@ -9342,7 +9333,6 @@ in
};
};
-
hardware = {
enableAllFirmware = lib.mkForce true;
};
@@ -9358,6 +9348,7 @@ in
Port = servicePort;
MusicFolder = "/Vault/Eternor/Music";
PlaylistsPath = "./Playlists";
+ AutoImportPlaylists = false;
EnableSharing = true;
EnableTranscodingConfig = true;
Scanner.GroupAlbumReleases = true;
@@ -9384,6 +9375,7 @@ in
};
UILoginBackgroundUrl = "https://i.imgur.com/OMLxi7l.png";
UIWelcomeMessage = "~SwarselSound~";
+ EnableInsightsCollector = false;
};
};
@@ -9400,57 +9392,10 @@ in
enableACME = true;
forceSSL = true;
acmeRoot = null;
- locations = {
- "/" = {
- proxyPass = "http://navidrome";
- proxyWebsockets = true;
- extraConfig = ''
- auth_request /oauth2/auth;
- error_page 401 = /oauth2/sign_in;
-
- # pass information via X-User and X-Email headers to backend,
- # requires running with --set-xauthrequest flag (done by NixOS)
- auth_request_set $user $upstream_http_x_auth_request_user;
- auth_request_set $email $upstream_http_x_auth_request_email;
- proxy_set_header X-User $user;
- proxy_set_header X-Email $email;
-
- # if you enabled --pass-access-token, this will pass the token to the backend
- auth_request_set $token $upstream_http_x_auth_request_access_token;
- proxy_set_header X-Access-Token $token;
-
- # if you enabled --cookie-refresh, this is needed for it to work with auth_request
- auth_request_set $auth_cookie $upstream_http_set_cookie;
- add_header Set-Cookie $auth_cookie;
- proxy_redirect http:// https://;
- proxy_read_timeout 600s;
- proxy_send_timeout 600s;
- proxy_buffering off;
- proxy_request_buffering off;
- client_max_body_size 0;
- '';
- };
- "/oauth2/" = {
- proxyPass = "http://oauth2-proxy";
- extraConfig = ''
- proxy_set_header X-Scheme $scheme;
- proxy_set_header X-Auth-Request-Redirect $scheme://$host$request_uri;
- '';
- };
- "= /oauth2/auth" = {
- proxyPass = "http://oauth2-proxy/oauth2/auth";
- extraConfig = ''
- internal;
-
- proxy_set_header X-Scheme $scheme;
- # nginx auth_request includes headers but not body
- proxy_set_header Content-Length "";
- proxy_pass_request_body off;
- '';
- };
- "/share" = {
- proxyPass = "http://navidrome";
- proxyWebsockets = true;
+ oauth2.enable = true;
+ oauth2.allowedGroups = [ "navidrome_access" ];
+ locations =
+ let
extraConfig = ''
proxy_redirect http:// https://;
proxy_read_timeout 600s;
@@ -9458,25 +9403,29 @@ in
proxy_buffering off;
proxy_request_buffering off;
client_max_body_size 0;
- proxy_set_header X-User "";
- proxy_set_header X-Email "";
'';
+ in
+ {
+ "/" = {
+ proxyPass = "http://navidrome";
+ proxyWebsockets = true;
+ inherit extraConfig;
+ };
+ "/share" = {
+ proxyPass = "http://navidrome";
+ proxyWebsockets = true;
+ setOauth2Headers = false;
+ bypassAuth = true;
+ inherit extraConfig;
+ };
+ "/rest" = {
+ proxyPass = "http://navidrome";
+ proxyWebsockets = true;
+ setOauth2Headers = false;
+ bypassAuth = true;
+ inherit extraConfig;
+ };
};
- "/rest" = {
- proxyPass = "http://navidrome";
- proxyWebsockets = true;
- extraConfig = ''
- proxy_redirect http:// https://;
- proxy_read_timeout 600s;
- proxy_send_timeout 600s;
- proxy_buffering off;
- proxy_request_buffering off;
- client_max_body_size 0;
- proxy_set_header X-User "";
- proxy_set_header X-Email "";
- '';
- };
- };
};
};
};
@@ -9493,21 +9442,27 @@ in
{ lib, config, ... }:
+let
+ servicePort = 1025;
+ serviceName = "spotifyd";
+ serviceUser = "spotifyd";
+ serviceGroup = serviceUser;
+in
{
- options.swarselsystems.modules.server.spotifyd = lib.mkEnableOption "enable spotifyd on server";
- config = lib.mkIf config.swarselsystems.modules.server.spotifyd {
- users.groups.spotifyd = {
+ 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.spotifyd = {
+ users.users."${serviceUser}" = {
isSystemUser = true;
uid = 65136;
- group = "spotifyd";
+ group = serviceGroup;
extraGroups = [ "audio" "utmp" "pipewire" ];
};
- networking.firewall.allowedTCPPorts = [ 1025 ];
+ networking.firewall.allowedTCPPorts = [ servicePort ];
services.pipewire.systemWide = true;
@@ -9520,7 +9475,7 @@ in
device = "sysdefault:CARD=PCH";
device_name = "SwarselSpot";
mixer = "alsa";
- zeroconf_port = 1025;
+ zeroconf_port = servicePort;
};
};
};
@@ -9625,11 +9580,36 @@ in
{ config, lib, pkgs, ... }:
+let
+ serviceName = "postgresql";
+ postgresVersion = 14;
+in
+{
+ options.swarselsystems.modules.server."${serviceName}" = lib.mkEnableOption "enable ${serviceName} on server";
+ config = lib.mkIf config.swarselsystems.modules.server."${serviceName}" {
+ services = {
+ postgresql = {
+ enable = true;
+ package = pkgs."postgresql_${builtins.toString postgresVersion}";
+ dataDir = "/Vault/data/postgresql/${builtins.toString postgresVersion}";
+ };
+ };
+ };
+}
+
+{ config, lib, pkgs, sops, ... }:
+{ lib, config, pkgs, ... }:
let
matrixDomain = "swatrix.swarsel.win";
serviceName = "matrix";
@@ -9747,12 +9727,16 @@ in
matrix-synapse = {
enable = true;
+ dataDir = "/Vault/data/matrix-synapse";
settings = {
- app_service_config_files = [
- "/var/lib/matrix-synapse/telegram-registration.yaml"
- "/var/lib/matrix-synapse/whatsapp-registration.yaml"
- "/var/lib/matrix-synapse/signal-registration.yaml"
- "/var/lib/matrix-synapse/doublepuppet.yaml"
+ app_service_config_files = let
+ inherit (config.services.matrix-synapse) dataDir;
+ in
+ [
+ "${dataDir}/telegram-registration.yaml"
+ "${dataDir}/whatsapp-registration.yaml"
+ "${dataDir}/signal-registration.yaml"
+ "${dataDir}/doublepuppet.yaml"
];
server_name = matrixDomain;
public_baseurl = "https://${matrixDomain}";
@@ -9971,7 +9955,7 @@ in
{ pkgs, lib, config, ... }:
@@ -10007,7 +9991,7 @@ in
};
package = pkgs.nextcloud31;
hostName = serviceDomain;
- home = "/Vault/apps/nextcloud";
+ home = "/Vault/data/nextcloud";
datadir = "/Vault/data/nextcloud";
https = true;
configureRedis = true;
@@ -10052,7 +10036,7 @@ in
{ lib, config, ... }:
@@ -10077,7 +10061,7 @@ in
host = "0.0.0.0";
port = servicePort;
openFirewall = true;
- mediaLocation = "/Vault/Eternor/Immich";
+ mediaLocation = "/Vault/Eternor/Immich"; # dataDir
environment = {
IMMICH_MACHINE_LEARNING_URL = lib.mkForce "http://localhost:3003";
};
@@ -10127,7 +10111,7 @@ in
This is my personal document management system. It automatically pulls documents from several sources, the only manual step for physical documents is to put them in my scanner and use email delivery. @@ -10269,12 +10253,27 @@ in
{ self, pkgs, lib, config, ... }:
let
serviceDomain = "store.swarsel.win";
+ lidarrUser = "lidarr";
+ lidarrGroup = lidarrUser;
+ lidarrPort = 8686;
+ radarrUser = "radarr";
+ radarrGroup = radarrUser;
+ radarrPort = 7878;
+ sonarrUser = "sonarr";
+ sonarrGroup = sonarrUser;
+ sonarrPort = 8989;
+ readarrUser = "readarr";
+ readarrGroup = readarrUser;
+ readarrPort = 8787;
+ prowlarrUser = "prowlarr";
+ prowlarrGroup = prowlarrUser;
+ prowlarrPort = 9696;
in
{
options.swarselsystems.modules.server.transmission = lib.mkEnableOption "enable transmission and friends on server";
@@ -10286,11 +10285,11 @@ in
dockeruser = {
gid = 1155;
};
- radarr = { };
- readarr = { };
- sonarr = { };
- lidarr = { };
- prowlarr = { };
+ "${radarrGroup}" = { };
+ "${readarrGroup}" = { };
+ "${sonarrGroup}" = { };
+ "${lidarrGroup}" = { };
+ "${prowlarrGroup}" = { };
};
users = {
dockeruser = {
@@ -10299,29 +10298,29 @@ in
group = "docker";
extraGroups = [ "users" ];
};
- radarr = {
+ "${radarrUser}" = {
isSystemUser = true;
- group = "radarr";
+ group = radarrGroup;
extraGroups = [ "users" ];
};
- readarr = {
+ "${readarrGroup}" = {
isSystemUser = true;
- group = "readarr";
+ group = readarrGroup;
extraGroups = [ "users" ];
};
- sonarr = {
+ "${sonarrGroup}" = {
isSystemUser = true;
- group = "sonarr";
+ group = sonarrGroup;
extraGroups = [ "users" ];
};
- lidarr = {
+ "${lidarrUser}" = {
isSystemUser = true;
- group = "lidarr";
+ group = lidarrGroup;
extraGroups = [ "users" ];
};
- prowlarr = {
+ "${prowlarrGroup}" = {
isSystemUser = true;
- group = "prowlarr";
+ group = prowlarrGroup;
extraGroups = [ "users" ];
};
};
@@ -10347,32 +10346,45 @@ in
services = {
radarr = {
enable = true;
+ user = radarrUser;
+ group = radarrGroup;
+ settings.server.port = radarrPort;
openFirewall = true;
- dataDir = "/Vault/apps/radarr";
+ dataDir = "/Vault/data/radarr";
};
readarr = {
enable = true;
+ user = readarrUser;
+ group = readarrGroup;
+ settings.server.port = readarrPort;
openFirewall = true;
- dataDir = "/Vault/apps/readarr";
+ dataDir = "/Vault/data/readarr";
};
sonarr = {
enable = true;
+ user = sonarrUser;
+ group = sonarrGroup;
+ settings.server.port = sonarrPort;
openFirewall = true;
- dataDir = "/Vault/apps/sonarr";
+ dataDir = "/Vault/data/sonarr";
};
lidarr = {
enable = true;
+ user = lidarrUser;
+ group = lidarrGroup;
+ settings.server.port = lidarrPort;
openFirewall = true;
- dataDir = "/Vault/apps/lidarr";
+ dataDir = "/Vault/data/lidarr";
};
prowlarr = {
enable = true;
+ settings.server.port = prowlarrPort;
openFirewall = true;
};
nginx = {
virtualHosts = {
- "store.swarsel.win" = {
+ "${serviceDomain}" = {
enableACME = false;
forceSSL = false;
acmeRoot = null;
@@ -10384,31 +10396,31 @@ in
'';
};
"/radarr" = {
- proxyPass = "http://localhost:7878";
+ proxyPass = "http://localhost:${builtins.toString radarrPort}";
extraConfig = ''
client_max_body_size 0;
'';
};
"/readarr" = {
- proxyPass = "http://localhost:8787";
+ proxyPass = "http://localhost:${builtins.toString readarrPort}";
extraConfig = ''
client_max_body_size 0;
'';
};
"/sonarr" = {
- proxyPass = "http://localhost:8989";
+ proxyPass = "http://localhost:${builtins.toString sonarrPort}";
extraConfig = ''
client_max_body_size 0;
'';
};
"/lidarr" = {
- proxyPass = "http://localhost:8686";
+ proxyPass = "http://localhost:${builtins.toString lidarrPort}";
extraConfig = ''
client_max_body_size 0;
'';
};
"/prowlarr" = {
- proxyPass = "http://localhost:9696";
+ proxyPass = "http://localhost:${builtins.toString prowlarrPort}";
extraConfig = ''
client_max_body_size 0;
'';
@@ -10426,7 +10438,7 @@ in
{ lib, config, ... }:
@@ -10457,7 +10469,7 @@ in
user = serviceUser;
group = serviceGroup;
dataDir = "/Vault/data/syncthing";
- configDir = "/Vault/apps/syncthing";
+ configDir = "/Vault/data/syncthing/.config/syncthing";
guiAddress = "0.0.0.0:${builtins.toString servicePort}";
openDefaultPorts = true; # opens ports TCP/UDP 22000 and UDP 21027 for discovery
relay.enable = false;
@@ -10515,16 +10527,16 @@ in
devices = [ "sync (@oracle)" "magicant" "${workHostName}" "moonside (@oracle)" ];
id = "hgp9s-fyq3p";
};
- "Documents" = {
- path = "/Vault/data/syncthing/Documents";
- type = "receiveonly";
- versioning = {
- type = "simple";
- params.keep = "5";
- };
- devices = [ "magicant" "${workHostName}" "moonside (@oracle)" ];
- id = "hgr3d-pfu3w";
- };
+ # "Documents" = {
+ # path = "/Vault/data/syncthing/Documents";
+ # type = "receiveonly";
+ # versioning = {
+ # type = "simple";
+ # params.keep = "5";
+ # };
+ # devices = [ "magicant" "${workHostName}" "moonside (@oracle)" ];
+ # id = "hgr3d-pfu3w";
+ # };
};
};
};
@@ -10560,7 +10572,7 @@ in
This manages backups for my pictures and obsidian files. @@ -10599,7 +10611,6 @@ in "/Vault/Eternor/Paperless" "/Vault/Eternor/Bilder" "/Vault/Eternor/Immich" - "/Vault/familymedia" ]; pruneOpts = [ "--keep-daily 3" @@ -10627,7 +10638,7 @@ in
This section exposes several metrics that I use to check the health of my server. I need to expand on the exporters section at some point, but for now I have everything I need. @@ -10858,7 +10869,7 @@ in
This is a WIP Jenkins instance. It is used to automatically build a new system when pushes to the main repository are detected. I have turned this service off for now however, as I actually prefer to start my builds manually. @@ -10866,30 +10877,40 @@ This is a WIP Jenkins instance. It is used to automatically build a new system w
{ pkgs, lib, config, ... }:
+let
+ serviceDomain = "servant.swarsel.win";
+ servicePort = 8088;
+ serviceName = "jenkins";
+in
{
- options.swarselsystems.modules.server.jenkins = lib.mkEnableOption "enable jenkins on server";
- config = lib.mkIf config.swarselsystems.modules.server.jenkins {
+ 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;
packages = [ pkgs.stdenv pkgs.git pkgs.jdk17 config.programs.ssh.package pkgs.nix ];
- listenAddress = "127.0.0.1";
+ listenAddress = "0.0.0.0";
home = "/Vault/apps/jenkins";
};
-
-
services.nginx = {
+ upstreams = {
+ "${serviceName}" = {
+ servers = {
+ "192.168.1.2:${builtins.toString servicePort}" = { };
+ };
+ };
+ };
virtualHosts = {
- "servant.swarsel.win" = {
+ "${serviceDomain}" = {
enableACME = true;
forceSSL = true;
acmeRoot = null;
locations = {
"/" = {
- proxyPass = "http://localhost:8088";
+ proxyPass = "http://${serviceName}";
extraConfig = ''
client_max_body_size 0;
'';
@@ -10906,7 +10927,7 @@ This is a WIP Jenkins instance. It is used to automatically build a new system w
This was an approach of hosting an RSS server from within emacs. That would have been useful as it would have allowed me to allow my feeds from any device. However, it proved impossible to do bidirectional syncing, so I abandoned this configuration in favor of FreshRSS. @@ -10934,7 +10955,7 @@ This was an approach of hosting an RSS server from within emacs. That would have
FreshRSS is a more 'classical' RSS aggregator that I can just host as a distinct service. This also has its upsides because I jave more control over the state this way. @@ -10957,24 +10978,26 @@ FreshRSS claims to support HTTP header auth, but at least it does not work with let serviceName = "freshrss"; serviceDomain = "signpost.swarsel.win"; + serviceUser = "freshrss"; + serviceGroup = serviceName; in { options.swarselsystems.modules.server.freshrss = lib.mkEnableOption "enable freshrss on server"; config = lib.mkIf config.swarselsystems.modules.server.freshrss { - users.users.freshrss = { + users.users."${serviceUser}" = { extraGroups = [ "users" ]; - group = "freshrss"; + group = serviceGroup; isSystemUser = true; }; - users.groups.freshrss = { }; + users.groups."${serviceGroup}" = { }; sops = { secrets = { - fresh = { owner = "freshrss"; }; - "kanidm-freshrss-client" = { owner = "freshrss"; group = "freshrss"; mode = "0440"; }; - "oidc-crypto-key" = { owner = "freshrss"; group = "freshrss"; mode = "0440"; }; + fresh = { owner = serviceUser; }; + "kanidm-freshrss-client" = { owner = serviceUser; group = serviceGroup; mode = "0440"; }; + "oidc-crypto-key" = { owner = serviceUser; group = serviceGroup; mode = "0440"; }; }; # templates = { @@ -11030,95 +11053,60 @@ in enableACME = true; forceSSL = true; acmeRoot = null; + oauth2.enable = true; + oauth2.allowedGroups = [ "ttrss_access" ]; locations = { "/" = { proxyPass = "http://${serviceName}"; - extraConfig = '' - auth_request /oauth2/auth; - error_page 401 = /oauth2/sign_in; - - # pass information via X-User and X-Email headers to backend, - # requires running with --set-xauthrequest flag (done by NixOS) - auth_request_set $user $upstream_http_x_auth_request_user; - auth_request_set $email $upstream_http_x_auth_request_email; - proxy_set_header X-User $user; - proxy_set_header X-Email $email; - proxy_set_header Remote-User $user; - - # if you enabled --pass-access-token, this will pass the token to the backend - auth_request_set $token $upstream_http_x_auth_request_access_token; - proxy_set_header X-Access-Token $token; - - # if you enabled --cookie-refresh, this is needed for it to work with auth_request - auth_request_set $auth_cookie $upstream_http_set_cookie; - add_header Set-Cookie $auth_cookie; - ''; - }; - "/oauth2/" = { - proxyPass = "http://oauth2-proxy"; - extraConfig = '' - proxy_set_header X-Scheme $scheme; - proxy_set_header X-Auth-Request-Redirect $scheme://$host$request_uri; - ''; - }; - "= /oauth2/auth" = { - proxyPass = "http://oauth2-proxy/oauth2/auth"; - extraConfig = '' - internal; - - proxy_set_header X-Scheme $scheme; - # nginx auth_request includes headers but not body - proxy_set_header Content-Length ""; - proxy_pass_request_body off; - ''; }; "/api" = { proxyPass = "http://${serviceName}"; + setOauth2Headers = false; + bypassAuth = true; }; }; }; }; }; }; - }
{ lib, config, pkgs, ... }:
let
- forgejoDomain = "swagit.swarsel.win";
+ serviceDomain = "swagit.swarsel.win";
+ servicePort = 3000;
+ serviceUser = "forgejo";
+ serviceGroup = serviceUser;
+ serviceName = "forgejo";
in
{
- options.swarselsystems.modules.server.forgejo = lib.mkEnableOption "enable forgejo on server";
- config = lib.mkIf config.swarselsystems.modules.server.forgejo {
+ options.swarselsystems.modules.server."${serviceName}" = lib.mkEnableOption "enable ${serviceName} on server";
+ config = lib.mkIf config.swarselsystems.modules.server."${serviceName}" {
- networking.firewall.allowedTCPPorts = [ 3000 ];
+ networking.firewall.allowedTCPPorts = [ servicePort ];
- users.users.forgejo = {
- group = "forgejo";
+ users.users."${serviceUser}" = {
+ group = serviceGroup;
isSystemUser = true;
};
- users.groups.forgejo = { };
+ users.groups."${serviceGroup}" = { };
sops.secrets = {
- kanidm-forgejo-client = {
- owner = "forgejo";
- group = "forgejo";
- mode = "0440";
- };
+ kanidm-forgejo-client = { owner = serviceUser; group = serviceGroup; mode = "0440"; };
};
services.forgejo = {
enable = true;
- user = "forgejo";
- group = "forgejo";
+ user = serviceUser;
+ group = serviceGroup;
lfs.enable = lib.mkDefault true;
settings = {
DEFAULT = {
@@ -11126,10 +11114,10 @@ in
};
server = {
PROTOCOL = "http";
- HTTP_PORT = 3000;
+ HTTP_PORT = servicePort;
HTTP_ADDR = "0.0.0.0";
- DOMAIN = forgejoDomain;
- ROOT_URL = "https://${forgejoDomain}";
+ DOMAIN = serviceDomain;
+ ROOT_URL = "https://${serviceDomain}";
};
# federation.ENABLED = true;
service = {
@@ -11214,14 +11202,21 @@ in
};
services.nginx = {
+ upstreams = {
+ "${serviceName}" = {
+ servers = {
+ "192.168.1.2:${builtins.toString servicePort}" = { };
+ };
+ };
+ };
virtualHosts = {
- "swagit.swarsel.win" = {
+ "${serviceDomain}" = {
enableACME = true;
forceSSL = true;
acmeRoot = null;
locations = {
"/" = {
- proxyPass = "http://localhost:3000";
+ proxyPass = "http://${serviceName}";
extraConfig = ''
client_max_body_size 0;
'';
@@ -11238,18 +11233,20 @@ in
{ lib, config, ... }:
let
serviceDomain = "synki.swarsel.win";
+ servicePort = 27701;
+ serviceName = "ankisync";
in
{
- options.swarselsystems.modules.server.ankisync = lib.mkEnableOption "enable ankisync on server";
- config = lib.mkIf config.swarselsystems.modules.server.ankisync {
+ options.swarselsystems.modules.server."${serviceName}" = lib.mkEnableOption "enable ${serviceName} on server";
+ config = lib.mkIf config.swarselsystems.modules.server."${serviceName}" {
- networking.firewall.allowedTCPPorts = [ 22701 ];
+ networking.firewall.allowedTCPPorts = [ servicePort ];
sops.secrets.swarsel = { owner = "root"; };
@@ -11260,7 +11257,7 @@ in
services.anki-sync-server = {
enable = true;
- port = 27701;
+ port = servicePort;
address = "0.0.0.0";
openFirewall = true;
users = [
@@ -11272,6 +11269,13 @@ in
};
services.nginx = {
+ upstreams = {
+ "${serviceName}" = {
+ servers = {
+ "192.168.1.2:${builtins.toString servicePort}" = { };
+ };
+ };
+ };
virtualHosts = {
"${serviceDomain}" = {
enableACME = true;
@@ -11279,7 +11283,7 @@ in
acmeRoot = null;
locations = {
"/" = {
- proxyPass = "http://localhost:27701";
+ proxyPass = "http://${serviceName}";
extraConfig = ''
client_max_body_size 0;
'';
@@ -11295,9 +11299,9 @@ in
The forgejo configuration is a little broken and will show a 500 error when signing in through kanidm. However, when pressing back and refreshing the page, I am logged in. Currently I cannot be bothered to fix this.
@@ -11553,9 +11557,9 @@ in{ lib, config, ... }:
let
@@ -11564,7 +11568,113 @@ let
oauth2ProxyPort = 3004;
in
{
- options.swarselsystems.modules.server.oauth2Proxy = lib.mkEnableOption "enable oauth2-proxy on server";
+ options = {
+ swarselsystems.modules.server.oauth2Proxy = lib.mkEnableOption "enable oauth2-proxy on server";
+ services.nginx.virtualHosts = lib.mkOption {
+ type = lib.types.attrsOf (
+ lib.types.submodule (
+ { config, ... }:
+ {
+ options.oauth2 = {
+ enable = lib.mkEnableOption "access protection of this virtualHost using oauth2-proxy.";
+ allowedGroups = lib.mkOption {
+ type = lib.types.listOf lib.types.str;
+ default = [ ];
+ description = ''
+ A list of kanidm groups that are allowed to access this resource, or the
+ empty list to allow any authenticated client.
+ '';
+ };
+ X-User = lib.mkOption {
+ type = lib.types.str;
+ default = "$upstream_http_x_auth_request_user";
+ description = "The variable to set as X-User";
+ };
+ X-Email = lib.mkOption {
+ type = lib.types.str;
+ default = "$upstream_http_x_auth_request_email";
+ description = "The variable to set as X-Email";
+ };
+ X-Access-Token = lib.mkOption {
+ type = lib.types.str;
+ default = "$upstream_http_x_auth_request_access_token";
+ description = "The variable to set as X-Access-Token";
+ };
+ };
+ options.locations = lib.mkOption {
+ type = lib.types.attrsOf (
+ lib.types.submodule (locationSubmodule: {
+ options = {
+ setOauth2Headers = lib.mkOption {
+ type = lib.types.bool;
+ default = true;
+ description = "Whether to add oauth2 headers to this location. Only takes effect is oauth2 is actually enabled on the parent vhost.";
+ };
+ bypassAuth = lib.mkOption {
+ type = lib.types.bool;
+ default = false;
+ description = "Whether to set auth_request off for this location. Only takes effect is oauth2 is actually enabled on the parent vhost.";
+ };
+ };
+ config = lib.mkIf config.oauth2.enable {
+ extraConfig = lib.optionalString locationSubmodule.config.setOauth2Headers ''
+ proxy_set_header X-User $user;
+ proxy_set_header Remote-User $user;
+ proxy_set_header X-Email $email;
+ proxy_set_header X-Access-Token $token;
+ add_header Set-Cookie $auth_cookie;
+ '' + lib.optionalString locationSubmodule.config.bypassAuth ''
+ auth_request off;
+ '';
+ };
+ })
+ );
+ };
+ config = lib.mkIf config.oauth2.enable {
+ extraConfig = ''
+ auth_request /oauth2/auth;
+ error_page 401 = /oauth2/sign_in;
+
+ # set variables that can be used in locations.<name>.extraConfig
+ # pass information via X-User and X-Email headers to backend,
+ # requires running with --set-xauthrequest flag
+ auth_request_set $user ${config.oauth2.X-User};
+ auth_request_set $email ${config.oauth2.X-Email};
+ # if you enabled --pass-access-token, this will pass the token to the backend
+ auth_request_set $token ${config.oauth2.X-Access-Token};
+ # if you enabled --cookie-refresh, this is needed for it to work with auth_request
+ auth_request_set $auth_cookie $upstream_http_set_cookie;
+ '';
+ locations = {
+ "/oauth2/" = {
+ proxyPass = "http://oauth2-proxy";
+ setOauth2Headers = false;
+ bypassAuth = true;
+ extraConfig = ''
+ proxy_set_header X-Scheme $scheme;
+ proxy_set_header X-Auth-Request-Redirect $scheme://$host$request_uri;
+ '';
+ };
+ "= /oauth2/auth" = {
+ proxyPass = "http://oauth2-proxy/oauth2/auth" + lib.optionalString (config.oauth2.allowedGroups != [ ]) "?allowed_groups=${lib.concatStringsSep "," config.oauth2.allowedGroups}";
+ setOauth2Headers = false;
+ bypassAuth = true;
+ extraConfig = ''
+ internal;
+
+ proxy_set_header X-Scheme $scheme;
+ # nginx auth_request includes headers but not body
+ proxy_set_header Content-Length "";
+ proxy_pass_request_body off;
+ '';
+ };
+ };
+ };
+ }
+ )
+ );
+ };
+ };
config = lib.mkIf config.swarselsystems.modules.server.oauth2Proxy {
sops = {
@@ -11668,9 +11778,9 @@ in
{ self, lib, config, ... }:
let
@@ -11726,12 +11836,11 @@ in
"${fireflyDomain}" = {
locations = {
"/api" = {
+ setOauth2Headers = false;
extraConfig = ''
index index.php;
try_files $uri $uri/ /index.php?$query_string;
add_header Access-Control-Allow-Methods 'GET, POST, HEAD, OPTIONS';
- proxy_set_header X-User "";
- proxy_set_header X-Email "";
'';
};
};
@@ -11753,52 +11862,18 @@ in
enableACME = true;
forceSSL = true;
acmeRoot = null;
+ oauth2.enable = true;
+ oauth2.allowedGroups = [ "firefly_access" ];
# main config is automatically added by nixos firefly config.
# hence, only provide certificate
locations = {
"/" = {
proxyPass = "http://${serviceName}";
- extraConfig = ''
- auth_request /oauth2/auth;
- error_page 401 = /oauth2/sign_in;
-
- # pass information via X-User and X-Email headers to backend,
- # requires running with --set-xauthrequest flag (done by NixOS)
- auth_request_set $user $upstream_http_x_auth_request_user;
- auth_request_set $email $upstream_http_x_auth_request_email;
- proxy_set_header X-User $user;
- proxy_set_header X-Email $email;
-
- # if you enabled --pass-access-token, this will pass the token to the backend
- auth_request_set $token $upstream_http_x_auth_request_access_token;
- proxy_set_header X-Access-Token $token;
-
- # if you enabled --cookie-refresh, this is needed for it to work with auth_request
- auth_request_set $auth_cookie $upstream_http_set_cookie;
- add_header Set-Cookie $auth_cookie;
- '';
- };
- "/oauth2/" = {
- proxyPass = "http://oauth2-proxy";
- extraConfig = ''
-
- proxy_set_header X-Scheme $scheme;
- proxy_set_header X-Auth-Request-Redirect $scheme://$host$request_uri;
- '';
- };
- "= /oauth2/auth" = {
- proxyPass = "http://oauth2-proxy/oauth2/auth";
- extraConfig = ''
- internal;
-
- proxy_set_header X-Scheme $scheme;
- # nginx auth_request includes headers but not body
- proxy_set_header Content-Length "";
- proxy_pass_request_body off;
- '';
};
"/api" = {
proxyPass = "http://${serviceName}";
+ setOauth2Headers = false;
+ bypassAuth = true;
};
};
};
@@ -11810,9 +11885,9 @@ in
{ self, lib, config, ... }:
let
@@ -12149,8 +12224,8 @@ This smashes Atmosphere 1.3.2 on the switch, which is what I am currenty using.
This holds configuration that is specific to framework laptops. @@ -12188,8 +12263,8 @@ This holds configuration that is specific to framework laptops.
{ lib, config, ... }:
@@ -12205,8 +12280,8 @@ This holds configuration that is specific to framework laptops.
{ lib, config, ... }:
@@ -12228,8 +12303,8 @@ This holds configuration that is specific to framework laptops.
{ lib, config, ... }:
@@ -12260,8 +12335,8 @@ This holds configuration that is specific to framework laptops.
{ lib, config, ... }:
@@ -15206,8 +15281,8 @@ The `extraConfig` section here CANNOT be reindented. This has something to do wi
{ lib, config, ... }:
@@ -16349,7 +16424,7 @@ in
{ command = "OBSIDIAN_USE_WAYLAND=1 obsidian"; }
{ command = "nm-applet"; }
{ command = "feishin"; }
- { command = "teams-for-linux"; }
+ { command = "teams-for-linux --disableGpu=true --minimized=true --trayIconEnabled=true"; }
{ command = "1password"; }
];
monitors = {
@@ -16453,8 +16528,8 @@ in
This holds configuration that is specific to framework laptops. @@ -20294,8 +20369,8 @@ autocmd DocStart vc-impimba-1.m.imp.ac.at/ui/webconsole mode ignore
@@ -20792,7 +20867,7 @@ sync USER HOST: