diff --git a/assets/wallpaper.jpg b/assets/wallpaper.jpg index b9663ff..ab0b16d 100644 Binary files a/assets/wallpaper.jpg and b/assets/wallpaper.jpg differ diff --git a/assets/wallpaper2.jpg b/assets/wallpaper2.jpg deleted file mode 100644 index ab0b16d..0000000 Binary files a/assets/wallpaper2.jpg and /dev/null differ diff --git a/assets/wallpaper3.jpg b/assets/wallpaper3.jpg deleted file mode 100644 index 8efdd50..0000000 Binary files a/assets/wallpaper3.jpg and /dev/null differ diff --git a/assets/wallpaper4.jpg b/assets/wallpaper4.jpg deleted file mode 100644 index ca554c7..0000000 Binary files a/assets/wallpaper4.jpg and /dev/null differ diff --git a/assets/wallpaper5.jpg b/assets/wallpaper5.jpg deleted file mode 100644 index a1d33a4..0000000 Binary files a/assets/wallpaper5.jpg and /dev/null differ diff --git a/assets/wallpaper6.jpg b/assets/wallpaper6.jpg deleted file mode 100644 index 67453a2..0000000 Binary files a/assets/wallpaper6.jpg and /dev/null differ diff --git a/home/common/optional/desktop/hyprland.nix b/home/common/optional/desktop/hyprland.nix deleted file mode 100644 index 4bb441a..0000000 --- a/home/common/optional/desktop/hyprland.nix +++ /dev/null @@ -1,18 +0,0 @@ -{ pkgs, pkgs-unstable, ... }: -let - scripts = import ./hyprland/scripts/default.nix { inherit pkgs; }; -in -{ - imports = [ - (import ./hyprland/hyprland.nix { inherit pkgs scripts pkgs-unstable; }) - (import ./hyprland/wallpaper.nix { inherit pkgs scripts; }) - (import ./hyprland/hyprlock.nix { inherit pkgs scripts; }) - (import ./hyprland/hypridle.nix { inherit pkgs scripts; }) - ./hyprland/notifications.nix - ]; - - - - -} - diff --git a/home/common/optional/desktop/hyprland/hyprland.nix b/home/common/optional/desktop/hyprland/hyprland.nix deleted file mode 100644 index 9ffb2e4..0000000 --- a/home/common/optional/desktop/hyprland/hyprland.nix +++ /dev/null @@ -1,353 +0,0 @@ -{ pkgs, pkgs-unstable, scripts, ... }: -{ - imports = [ - ./hyprland/performance.nix - ]; - - wayland.windowManager.hyprland = { - enable = true; - systemd.enable = false; - - plugins = with pkgs; [ - (hyprlandPlugins.mkHyprlandPlugin { - pluginName = "hyprselect"; - version = "0.1"; - src = fetchFromGitHub { - owner = "jmanc3"; - repo = "hyprselect"; - rev = "f9651b5fd64c730ee164a6fee6a08d0398dcbe0a"; - hash = "sha256-tY8EdfsjlUOuQ9v/POqpyLlkRO5wqEVSE9UeHfXuaGk="; - }; - - inherit (hyprland) nativeBuildInputs; - - meta = with lib; { - homepage = "https://github.com/jmanc3/hyprselect"; - description = "A plugin that adds a completely useless desktop selection box to Hyprland"; - license = licenses.unlicense; - platforms = platforms.linux; - }; - }) - hyprlandPlugins.hyprscrolling - hyprlandPlugins.hyprbars - ]; - - settings = { - source = [ - "~/.config/koonos/current/performance/hyprland.conf" - ]; - - "$terminal" = "${pkgs.uwsm}/bin/uwsm-app -- ${pkgs.alacritty}/bin/alacritty"; - "$fileManager" = "${pkgs.uwsm}/bin/uwsm-app -- ${pkgs.pcmanfm}/bin/pcmanfm"; - "$browser" = "${pkgs.uwsm}/bin/uwsm-app -- zen-beta"; - "$menu" = "${pkgs.walker}/bin/walker"; - "$player" = "${pkgs.playerctl}/bin/playerctl"; - - monitor = [ - "eDP-1,preferred,1721x1080,auto" - "HDMI-A-1,preferred,1450x0,auto" - ]; - - exec-once = [ - "${pkgs.uwsm}/bin/uwsm-app -- ${pkgs.hypridle}/bin/hypridle" - "${pkgs.uwsm}/bin/uwsm-app -- ${pkgs.waybar}/bin/waybar" - "${pkgs.uwsm}/bin/uwsm-app -- ${pkgs.hyprpaper}/bin/hyprpaper" - "sleep 2 && pw-play --volume=0 ~/Downloads/empty.wav" - ]; - - env = [ - "HYPRCURSOR_THEME,macOS" - "HYPRCURSOR_SIZE,20" - ]; - - # env = [ - # "XCURSOR_SIZE,20" - # "XCURSOR_THEME,macOS" - # ]; - - general = { - gaps_in = 0; - gaps_out = 0; - - border_size = 2; - - "col.active_border" = "rgba(33ccffee) rgba(00ff99ee) 45deg"; - "col.inactive_border" = "rgba(595959aa)"; - - # Set to true enable resizing windows by clicking and dragging on borders and gaps - resize_on_border = true; - - # Please see https://wiki.hyprland.org/Configuring/Tearing/ before you turn this on - allow_tearing = false; - - layout = "scrolling"; - }; - - decoration = { - # rounding = 10 - # rounding_power = 2 - - # Change transparency of focused and unfocused windows - active_opacity = 1.0; - inactive_opacity = 1.0; - - shadow = { - # enabled = false; - range = 4; - render_power = 3; - color = "rgba(1a1a1aee)"; - }; - - # https://wiki.hyprland.org/Configuring/Variables/#blur - blur = { - # enabled = false; - size = 3; - passes = 1; - - vibrancy = 0.1696; - }; - }; - - - # https://wiki.hyprland.org/Configuring/Variables/#animations - animations = { - enabled = true; - - # Default animations, see https://wiki.hyprland.org/Configuring/Animations/ for more - bezier = [ - "easeOutQuint,0.23,1,0.32,1" - "easeInOutCubic,0.65,0.05,0.36,1" - "linear,0,0,1,1" - "almostLinear,0.5,0.5,0.75,1.0" - "quick,0.15,0,0.1,1" - - ]; - - animation = [ - "global, 1, 10, default" - "border, 0, 5.39, easeOutQuint" - "windows, 1, 4.79, easeOutQuint" - "windowsIn, 1, 4.1, easeOutQuint, popin 87%" - "windowsOut, 1, 1.49, linear, popin 87%" - "fadeIn, 1, 1.73, almostLinear" - "fadeOut, 1, 1.46, almostLinear" - "fade, 1, 3.03, quick" - "layers, 1, 3.81, easeOutQuint" - "layersIn, 1, 4, easeOutQuint, fade" - "layersOut, 1, 1.5, linear, fade" - "fadeLayersIn, 1, 1.79, almostLinear" - "fadeLayersOut, 1, 1.39, almostLinear" - "workspaces, 0, 1.94, almostLinear, fade" - "workspacesIn, 0, 1.21, almostLinear, fade" - "workspacesOut, 0, 1.94, almostLinear, fade" - ]; - }; - - - dwindle = { - pseudotile = true; # Master switch for pseudotiling. Enabling is bound to mainMod + P in the keybinds section below - preserve_split = true; # You probably want this - }; - - # See https://wiki.hyprland.org/Configuring/Master-Layout/ for more - master = { - new_status = "master"; - }; - - # https://wiki.hyprland.org/Configuring/Variables/#misc - misc = { - force_default_wallpaper = 0; # Set to 0 or 1 to disable the anime mascot wallpapers - disable_hyprland_logo = true; - disable_splash_rendering = true; - }; - - - ############# - ### INPUT ### - ############# - - # https://wiki.hyprland.org/Configuring/Variables/#input - input = { - kb_layout = "us"; - # kb_variant = - # kb_model = - kb_options = "caps:swapescape"; - # kb_rules = - - follow_mouse = 1; - - sensitivity = 0; # -1.0 - 1.0, 0 means no modification. - repeat_rate = 35; - repeat_delay = 300; - - touchpad = { - natural_scroll = true; - tap-to-click = false; - clickfinger_behavior = true; - }; - }; - - # https://wiki.hyprland.org/Configuring/Variables/#gestures - # gestures = { - # workspace_swipe = true; - # }; - - # See https://wiki.hyprland.org/Configuring/Keywords/ - "$mainMod" = "SUPER"; # Sets "Windows" key as main modifier - bind = [ - - # Example binds, see https://wiki.hyprland.org/Configuring/Binds/ for more - "$mainMod, return, exec, $terminal" - "$mainMod, W, killactive," - # bind = $mainMod, M, exit, - "$mainMod, E, exec, $fileManager" - "$mainMod, B, exec, $browser" - - "$mainMod, M, exec, $terminal -e ${pkgs-unstable.gurk-rs}/bin/gurk" - "$mainMod, P, exec, $terminal -e ${pkgs.ncmpcpp}/bin/ncmpcpp" - "$mainMod SHIFT, B, exec, $terminal -e \"$EDITOR\" /home/max/bible.txt -R" - "$mainMod SHIFT, R, exec, ${pkgs.hyprshot}/bin/hyprshot -m region --clipboard-only" - - # "$mainMod, V, togglefloating," - "$mainMod, space, exec, $menu" - # "$mainMod, P, pseudo, # dwindle" - "$mainMod, F, fullscreen" - # bind = $mainMod, J, togglesplit, # dwindle - - "$mainMod SHIFT, Q, exec, ${scripts.lock}" - - # Move focus with mainMod + arrow keys - "$mainMod, H, movefocus, l" - "$mainMod, L, movefocus, r" - "$mainMod, K, movefocus, u" - "$mainMod, J, movefocus, d" - - # Swap window with mainMod + shift + arrow keys - "$mainMod SHIFT, H, swapwindow, l" - "$mainMod SHIFT, L, swapwindow, r" - "$mainMod SHIFT, K, swapwindow, u" - "$mainMod SHIFT, J, swapwindow, d" - - # "$mainMod ALT, H, resizeactive, -40 0" - # "$mainMod ALT, L, resizeactive, 40 0" - - # Switch workspaces with mainMod + [0-9] - "$mainMod, 1, workspace, 1" - "$mainMod, 2, workspace, 2" - "$mainMod, 3, workspace, 3" - "$mainMod, 4, workspace, 4" - "$mainMod, 5, workspace, 5" - "$mainMod, 6, workspace, 6" - "$mainMod, 7, workspace, 7" - "$mainMod, 8, workspace, 8" - "$mainMod, 9, workspace, 9" - "$mainMod, 0, workspace, 10" - - # Move active window to a workspace with mainMod + SHIFT + [0-9] - "$mainMod SHIFT, 1, movetoworkspace, 1" - "$mainMod SHIFT, 2, movetoworkspace, 2" - "$mainMod SHIFT, 3, movetoworkspace, 3" - "$mainMod SHIFT, 4, movetoworkspace, 4" - "$mainMod SHIFT, 5, movetoworkspace, 5" - "$mainMod SHIFT, 6, movetoworkspace, 6" - "$mainMod SHIFT, 7, movetoworkspace, 7" - "$mainMod SHIFT, 8, movetoworkspace, 8" - "$mainMod SHIFT, 9, movetoworkspace, 9" - "$mainMod SHIFT, 0, movetoworkspace, 10" - - # Example special workspace (scratchpad) - "$mainMod, S, togglespecialworkspace, magic" - "$mainMod SHIFT, S, movetoworkspace, special:magic" - - # Scroll through existing workspaces with mainMod + scroll - # "$mainMod, mouse_down, workspace, e+1" - # "$mainMod, mouse_up, workspace, e-1" - - ", Prior, exec, ${pkgs.ydotool}/bin/ydotool click --next-delay 0 0x40" - ", Next, exec, ${pkgs.ydotool}/bin/ydotool click --next-delay 0 0x41" - ]; - - bindr = [ - ", Prior, exec, ${pkgs.ydotool}/bin/ydotool click --next-delay 0 0x80" - ", Next, exec, ${pkgs.ydotool}/bin/ydotool click --next-delay 0 0x81" - ]; - - # Move/resize windows with mainMod + LMB/RMB and dragging - bindm = [ - "$mainMod, mouse:272, movewindow" - "$mainMod, mouse:273, resizewindow" - ]; - - "$osdclient" = "swayosd-client --monitor \"$(hyprctl monitors -j | ${pkgs.jq}/bin/jq -r '.[] | select(.focused == true).name')\""; - - bindel = [ - # Laptop multimedia keys for volume and LCD brightness - # bindel = ,XF86AudioRaiseVolume, exec, wpctl set-volume -l 1 @DEFAULT_AUDIO_SINK@ 5%+ - # bindel = ,XF86AudioLowerVolume, exec, wpctl set-volume @DEFAULT_AUDIO_SINK@ 5%- - ",XF86AudioRaiseVolume, exec, $osdclient --output-volume=raise" - ",XF86AudioLowerVolume, exec, $osdclient --output-volume=lower" - ",XF86AudioMute, exec, wpctl set-mute @DEFAULT_AUDIO_SINK@ toggle" - ",XF86AudioMicMute, exec, wpctl set-mute @DEFAULT_AUDIO_SOURCE@ toggle" - # bindel = ,XF86MonBrightnessUp, exec, brightnessctl -e4 -n2 set 5%+ - # bindel = ,XF86MonBrightnessDown, exec, brightnessctl -e4 -n2 set 5%- - ",XF86MonBrightnessUp, exec, $osdclient --brightness=raise" - ",XF86MonBrightnessDown, exec, $osdclient --brightness=lower" - ]; - - bindl = [ - # Requires playerctl - ", XF86AudioNext, exec, $player next" - ", XF86AudioPause, exec, $player play-pause" - ", XF86AudioPlay, exec, $player play-pause" - ", XF86AudioPrev, exec, $player previous" - ]; - - bindd = [ - "$mainMod, C, Universal copy, sendshortcut, CTRL, Insert," - "$mainMod, V, Universal paste, sendshortcut, SHIFT, Insert," - "$mainMod, X, Universal cut, sendshortcut, CTRL, X," - "$mainMod, A, Universal select all, sendshortcut, CTRL, A," - "$mainMod, T, Universal new tab, sendshortcut, CTRL, T," - - "$mainMod ALT, H, Universal left, sendshortcut, , Left," - "$mainMod ALT, J, Universal down, sendshortcut, , Down," - "$mainMod ALT, K, Universal up, sendshortcut, , Up," - "$mainMod ALT, L, Universal right, sendshortcut, , Right," - - "$mainMod SHIFT ALT, H, Universal left, sendshortcut, SHIFT, Left," - "$mainMod SHIFT ALT, J, Universal down, sendshortcut, SHIFT, Down," - "$mainMod SHIFT ALT, K, Universal up, sendshortcut, SHIFT, Up," - "$mainMod SHIFT ALT, L, Universal right, sendshortcut, SHIFT, Right," - ]; - - windowrule = [ - # Just dash of opacity by default - "opacity 0.97 0.9, class:.*" - - # Ignore maximize requests from apps. You'll probably like this. - "suppressevent maximize, class:.*" - - # Fix some dragging issues with XWayland - "nofocus,class:^$,title:^$,xwayland:1,floating:1,fullscreen:0,pinned:0" - ]; - - plugin = { - hyprselect = { - "col.main" = "rgba(ffffff25)"; - "col.border" = "rgba(ffffff88)"; - - fade_time_ms = 165.0; - - border_size = 1.0; - }; - hyprscrolling = { - fullscreen_on_one_column = true; - }; - - hyprbars = { - enabled = false; - }; - }; - }; - }; -} diff --git a/home/common/optional/desktop/hyprland/hyprland/performance.nix b/home/common/optional/desktop/hyprland/hyprland/performance.nix deleted file mode 100644 index 28b6df0..0000000 --- a/home/common/optional/desktop/hyprland/hyprland/performance.nix +++ /dev/null @@ -1,37 +0,0 @@ -{ pkgs, lib, ... }: -let - normal = { - decoration = { - blur.enabled = true; - shadow.enabled = true; - }; - misc.vfr = false; - }; - battery-saver = { - decoration = { - blur.enabled = false; - shadow.enabled = false; - }; - misc.vfr = true; - }; - - normal-file = pkgs.writeText "hyprland.conf.normal" (lib.hm.generators.toHyprconf { attrs = normal; }); - battery-saver-file = pkgs.writeText "hyprland.conf.battery" (lib.hm.generators.toHyprconf { attrs = battery-saver; }); - - switchScript = pkgs.writeShellScriptBin "switch-config" '' - TARGET="$HOME/.config/koonos/current/performance/hyprland.conf" - - if [ "$(readlink "$TARGET")" = "${normal-file}" ]; then - ln -sf ${battery-saver-file} "$TARGET" - echo "Switched to battery saver" - else - ln -sf ${normal-file} "$TARGET" - echo "Switched to normal mode" - fi - ''; -in -{ - home.file.".config/koonos/current/performance/hyprland.conf".source = normal-file; - - home.packages = [ switchScript ]; -} diff --git a/home/common/optional/desktop/hyprland/scripts/default.nix b/home/common/optional/desktop/hyprland/scripts/default.nix deleted file mode 100644 index 4932de8..0000000 --- a/home/common/optional/desktop/hyprland/scripts/default.nix +++ /dev/null @@ -1,7 +0,0 @@ -{ pkgs }: -{ - lock = - pkgs.writeShellScript "koonos-lock-screen" '' - ${pkgs.hyprlock}/bin/hyprlock - ''; -} diff --git a/host/ark/default.nix b/host/ark/default.nix deleted file mode 100644 index 89d6fe0..0000000 --- a/host/ark/default.nix +++ /dev/null @@ -1,78 +0,0 @@ -{ config, lib, pkgs, ... }: { - imports = [ - ./hardware-configuration.nix - ./options.nix - ../common/core/default.nix - ./user.nix - ./sops.nix - - ./service/audio.nix - ./service/auth.nix - ./service/docs.nix - ./service/git.nix - ./service/home.nix - ./service/photos.nix - ./service/radicale.nix - ./service/wakapi.nix - - # ./service/elytra.nix - ./service/money.nix - ]; - - # Use the systemd-boot EFI boot loader. - boot.loader.systemd-boot.enable = true; - boot.loader.efi.canTouchEfiVariables = true; - - networking.hostName = "ark"; - networking.nameservers = [ "8.8.8.8" "1.1.1.1" ]; - services.tailscale = { - enable = true; - useRoutingFeatures = "both"; - extraUpFlags = [ "--accept-dns=false" ]; - }; - - oauth.name = "KoonFamily"; - oauth.secrets = import ./oauth-secrets.nix; - - security.sudo.wheelNeedsPassword = false; - - services.cloudflared = { - enable = true; - tunnels = { - "91d31395-fbc7-45a1-ae13-148957b32ecd" = { - credentialsFile = config.sops.secrets.tunnel-credentials.path; - ingress = { - "auth.koon.us" = "http://localhost:1411"; - "photos.koon.us" = "http://localhost:2283"; - "home.koon.us" = "http://localhost:8123"; - "docs.koon.us" = "http://localhost:3004"; - "git.koon.us" = "http://localhost:3000"; - "ssh.koon.us" = "ssh://localhost:2222"; - "audio.koon.us" = "http://localhost:8021"; - "radicale.koon.us" = "http://localhost:5232"; - "waka.koon.us" = "http://localhost:3006"; - # "ride.koon.us" = "http://localhost:3007"; - # "ride-api.koon.us" = "http://localhost:8080"; - - "money.koon.us" = "http://localhost:3160"; - "zero.koon.us" = "http://localhost:4848"; - "money-api.koon.us" = "http://localhost:3161"; - - }; - default = "http_status:404"; - }; - }; - }; - - fileSystems."/mnt/hdd" = { - device = "/dev/sdb"; - fsType = "ext4"; - }; - - services.openssh.enable = true; - - networking.firewall.allowedTCPPorts = [ 8123 22 ]; - - system.stateVersion = "25.05"; # Did you read the comment? -} - diff --git a/host/ark/options.nix b/host/ark/options.nix deleted file mode 100644 index c4233cf..0000000 --- a/host/ark/options.nix +++ /dev/null @@ -1,7 +0,0 @@ -{ lib, ... }: { - options.oauth = { - name = lib.mkOption { type = lib.types.str; }; - secrets = lib.mkOption { type = lib.types.attrs; }; - }; - -} diff --git a/host/ark/service/audio.nix b/host/ark/service/audio.nix deleted file mode 100644 index 9840857..0000000 --- a/host/ark/service/audio.nix +++ /dev/null @@ -1,6 +0,0 @@ -{ ... }: { - services.audiobookshelf = { - enable = true; - port = 8021; - }; -} diff --git a/host/ark/service/auth.nix b/host/ark/service/auth.nix deleted file mode 100644 index f6089ec..0000000 --- a/host/ark/service/auth.nix +++ /dev/null @@ -1,19 +0,0 @@ -{ config, pkgs, ... }: { - services.pocket-id = { - enable = true; - settings = { - APP_URL = "https://auth.koon.us"; - TRUST_PROXY = true; - ANALYTICS_DISABLED = true; - - UI_CONFIG_DISABLED = true; - - APP_NAME = config.oauth.name; - - }; - - credentials = { - ENCRYPTION_KEY = config.sops.secrets."pocket-id-encryption-key".path; - }; - }; -} diff --git a/host/ark/service/docs.nix b/host/ark/service/docs.nix deleted file mode 100644 index 5ee323a..0000000 --- a/host/ark/service/docs.nix +++ /dev/null @@ -1,75 +0,0 @@ -{ config, lib, pkgs, ... }: { - nixpkgs.config.allowUnfree = true; - - services.outline = { - enable = true; - publicUrl = "https://docs.koon.us"; - port = 3004; - forceHttps = true; - storage.storageType = "local"; - logo = "https://i.imgur.com/fKJ1I63.png"; - oidcAuthentication = { - authUrl = "https://auth.koon.us/authorize"; - tokenUrl = "https://auth.koon.us/api/oidc/token"; - userinfoUrl = "https://auth.koon.us/api/oidc/userinfo"; - clientId = ""; - clientSecretFile = config.sops.secrets."docs/clientSecret".path; - scopes = [ "openid" "email" "profile" ]; - usernameClaim = "preferred_username"; - displayName = config.oauth.name; - }; - }; - - systemd.services.outline = { - script = - let - localPostgresqlUrl = "postgres://localhost/outline?host=/run/postgresql"; - cfg = config.services.outline; - in lib.mkForce '' - export SECRET_KEY="$(head -n1 ${lib.escapeShellArg cfg.secretKeyFile})" - export UTILS_SECRET="$(head -n1 ${lib.escapeShellArg cfg.utilsSecretFile})" - ${lib.optionalString (cfg.storage.storageType == "s3") '' - export AWS_SECRET_ACCESS_KEY="$(head -n1 ${lib.escapeShellArg cfg.storage.secretKeyFile})" - ''} - ${lib.optionalString (cfg.slackAuthentication != null) '' - export SLACK_CLIENT_SECRET="$(head -n1 ${lib.escapeShellArg cfg.slackAuthentication.secretFile})" - ''} - ${lib.optionalString (cfg.googleAuthentication != null) '' - export GOOGLE_CLIENT_SECRET="$(head -n1 ${lib.escapeShellArg cfg.googleAuthentication.clientSecretFile})" - ''} - ${lib.optionalString (cfg.azureAuthentication != null) '' - export AZURE_CLIENT_SECRET="$(head -n1 ${lib.escapeShellArg cfg.azureAuthentication.clientSecretFile})" - ''} - ${lib.optionalString (cfg.oidcAuthentication != null) '' - export OIDC_CLIENT_SECRET="$(head -n1 ${lib.escapeShellArg cfg.oidcAuthentication.clientSecretFile})" - export OIDC_CLIENT_ID="$(cat ${config.sops.secrets."docs/clientId".path})" - ''} - ${lib.optionalString (cfg.sslKeyFile != null) '' - export SSL_KEY="$(head -n1 ${lib.escapeShellArg cfg.sslKeyFile})" - ''} - ${lib.optionalString (cfg.sslCertFile != null) '' - export SSL_CERT="$(head -n1 ${lib.escapeShellArg cfg.sslCertFile})" - ''} - ${lib.optionalString (cfg.slackIntegration != null) '' - export SLACK_VERIFICATION_TOKEN="$(head -n1 ${lib.escapeShellArg cfg.slackIntegration.verificationTokenFile})" - ''} - ${lib.optionalString (cfg.smtp != null) '' - export SMTP_PASSWORD="$(head -n1 ${lib.escapeShellArg cfg.smtp.passwordFile})" - ''} - - ${ - if (cfg.databaseUrl == "local") then - '' - export DATABASE_URL=${lib.escapeShellArg localPostgresqlUrl} - export PGSSLMODE=disable - '' - else - '' - export DATABASE_URL=${lib.escapeShellArg cfg.databaseUrl} - '' - } - - ${cfg.package}/bin/outline-server - ''; - }; -} diff --git a/host/ark/service/elytra.nix b/host/ark/service/elytra.nix deleted file mode 100644 index e87fcef..0000000 --- a/host/ark/service/elytra.nix +++ /dev/null @@ -1,112 +0,0 @@ -{ secrets, config, pkgs, elytrarides, ... }: - -{ - users.users.elytra-web = { - isSystemUser = true; - group = "elytra-web"; - description = "Elytra Rides web service user"; - }; - - users.users.backend = { - isSystemUser = true; - home = "/var/lib/elytra-backend"; - createHome = true; - group = "backend"; - }; - - users.groups.elytra-web = {}; - users.groups.backend = {}; - - systemd.services.elytra-web = { - description = "Elytra Rides Next.js Web Application"; - wantedBy = [ "multi-user.target" ]; - after = [ "network.target" ]; - - environment = { - PORT = "3007"; - HOST = "127.0.0.1"; - NODE_ENV = "production"; - }; - - serviceConfig = { - Type = "simple"; - User = "elytra-web"; - Group = "elytra-web"; - - WorkingDirectory = "${pkgs.web}/lib/node_modules/web"; - ExecStart = - "${pkgs.nodejs}/bin/node ${pkgs.web}/lib/node_modules/web/node_modules/next/dist/bin/next start"; - EnvironmentFile = config.sops.secrets."elytra-frontend-env".path; - - Restart = "on-failure"; - RestartSec = 10; - - # Security hardening - NoNewPrivileges = true; - PrivateTmp = true; - ProtectSystem = "strict"; - ProtectHome = true; - - StateDirectory = "elytra-web"; - StateDirectoryMode = "0750"; - - StandardOutput = "journal"; - StandardError = "journal"; - SyslogIdentifier = "elytra-web"; - }; - }; - - services.postgresql = { - enable = true; - ensureDatabases = [ "backend" ]; - ensureUsers = [ - { - name = "backend"; - ensureDBOwnership = true; - } - ]; - }; - services.redis = { - enable = true; - }; - - nixpkgs.overlays = [ - (final: prev: { - web = elytrarides.packages.${pkgs.system}.web.overrideAttrs (old: { - buildPhase = '' - export NEXT_PUBLIC_GOOGLE_MAPS_API_KEY="${config.environment.sessionVariables.NEXT_PUBLIC_GOOGLE_MAPS_API_KEY}" - ${old.buildPhase or "runHook preBuild; npm run build --if-present; runHook postBuild"} - ''; - }); - }) - ]; - - environment.sessionVariables.NEXT_PUBLIC_GOOGLE_MAPS_API_KEY = secrets.ark.elytra.google-maps-api-key; - - systemd.services.elytra-backend = { - description = "Elytra Rides Backend Service"; - after = [ "network.target" "postgresql.service" ]; - wants = [ "network-online.target" ]; - - serviceConfig = { - - ExecStart = "${elytrarides.packages.${pkgs.system}.backend}/bin/nujade_backend"; - ExecStartPre = [ - "${pkgs.diesel-cli}/bin/diesel --database-url=\"postgresql:///backend?user=backend\" migration run --migration-dir=${elytrarides.packages.${pkgs.system}.backend}/migrations" - ]; - - Restart = "always"; - RestartSec = 5; - User = "backend"; - WorkingDirectory = "/var/lib/elytra-backend"; - Environment = "RUST_LOG=info"; - EnvironmentFile = config.sops.secrets."elytra-backend-env".path; - }; - - environment = { - DATABASE_URL="postgresql:///backend?user=backend"; - }; - - wantedBy = [ "multi-user.target" ]; - }; -} diff --git a/host/ark/service/git.nix b/host/ark/service/git.nix deleted file mode 100644 index 64a4e59..0000000 --- a/host/ark/service/git.nix +++ /dev/null @@ -1,189 +0,0 @@ -{ lib, config, pkgs, ... }: { - - services.openssh = { - enable = true; - - # hostKeys = [ - # { path = "/etc/ssh/ssh_host_ed25519_key"; type = "ed25519"; } - # { path = "/etc/ssh/ssh_host_rsa_key"; type = "rsa"; bits = 4096; } - # ]; - - settings = { - # explicitly allow post-quantum KEX - KexAlgorithms = [ - "mlkem768x25519-sha256" - "sntrup761x25519-sha512" - "curve25519-sha256" - ]; - }; - }; - - services.gitea = { - enable = true; - user = "git"; - group = "git"; - database = { - user = "git"; - name = "git"; - type = "postgres"; - }; - settings = { - server = { - DOMAIN = "git.koon.us"; - ROOT_URL = "https://git.koon.us"; - HTTP_PORT = 3000; - LANDING_PAGE = "/max"; - SSH_DOMAIN = "ssh.koon.us"; - SSH_PORT = 2222; - START_SSH_SERVER = true; - }; - oauth2_client = { - ACCOUNT_LINKING = "auto"; - ENABLE_AUTO_REGISTRATION = true; - UPDATE_AVATAR = true; - USERNAME = "email"; - }; - service = { - DISABLE_REGISTRATION = true; - ENABLE_PASSWORD_SIGNIN_FORM = false; - ENABLE_PASSKEY_AUTHENTICATION = false; - - SHOW_MILESTONES_DASHBOARD_PAGE = false; - }; - "service.explore" = { - DISABLE_USERS_PAGE = true; - DISABLE_ORGANIZATIONS_PAGE = true; - DISABLE_CODE_PAGE = true; - }; - }; - }; - - users.users.git = { - isSystemUser = true; - group = "git"; - home = "/var/lib/gitea"; - description = "Git server (Gitea)"; - createHome = true; - }; - users.groups.git = { }; - - systemd.services.gitea = { - serviceConfig = { - RestartSec = "60"; # Retry every minute - }; - preStart = let - exe = lib.getExe config.services.gitea.package; - - clientIdPath = config.sops.secrets."git/clientId".path; - clientSecretPath = config.sops.secrets."git/clientSecret".path; - - args = lib.escapeShellArgs (lib.concatLists [ - [ "--name" config.oauth.name ] - [ "--provider" "openidConnect" ] - # [ "--key" config.oauth.secrets.git.clientId ] - [ - "--auto-discover-url" - "https://auth.koon.us/.well-known/openid-configuration" - ] - [ "--scopes" "email" ] - [ "--scopes" "profile" ] - [ "--group-claim-name" "groups" ] - [ "--admin-group" "admin" ] - [ "--skip-local-2fa" ] - ]); - in lib.mkAfter '' - CLIENT_ID=$(cat ${clientIdPath}) - CLIENT_SECRET=$(cat ${clientSecretPath}) - - provider_id=$(${exe} admin auth list | ${pkgs.gnugrep}/bin/grep -w '${config.oauth.name}' | cut -f1) - - if [[ -z "$provider_id" ]]; then - ${exe} admin auth add-oauth ${args} --key "$CLIENT_ID" --secret "$CLIENT_SECRET" - else - ${exe} admin auth update-oauth --id "$provider_id" ${args} --key "$CLIENT_ID" --secret "$CLIENT_SECRET" - fi - - mkdir -p /var/lib/gitea/custom/public/assets/img/ - - ln -sf ${ - ./git/assets/img/logo.svg - } /var/lib/gitea/custom/public/assets/img/logo.svg - ln -sf ${ - ./git/assets/img/favicon.svg - } /var/lib/gitea/custom/public/assets/img/favicon.svg - - mkdir -p /var/lib/gitea/custom/templates/base/ - ln -sf ${ - ./git/templates/base/head_navbar.tmpl - } /var/lib/gitea/custom/templates/base/head_navbar.tmpl - ln -sf ${ - ./git/templates/base/footer_content.tmpl - } /var/lib/gitea/custom/templates/base/footer_content.tmpl - - mkdir -p /var/lib/gitea/custom/templates/custom/ - ln -sf ${ - ./git/templates/custom/header.tmpl - } /var/lib/gitea/custom/templates/custom/header.tmpl - - ''; - }; - - services.restic.backups = { - git-local = { - repository = "/mnt/hdd/restic/git"; - passwordFile = config.sops.secrets.restic-password.path; - initialize = true; - paths = [ "/var/lib/gitea/repositories" "/var/backup/git" ]; - backupPrepareCommand = '' - mkdir -p /var/backup/git - - ${pkgs.sudo}/bin/sudo ${pkgs.systemd}/bin/systemctl stop gitea - - ${pkgs.sudo}/bin/sudo -u postgres ${pkgs.postgresql}/bin/pg_dump \ - --clean \ - --if-exists \ - --dbname=git > /var/backup/git/postgres.sql - ''; - backupCleanupCommand = '' - ${pkgs.sudo}/bin/sudo ${pkgs.systemd}/bin/systemctl start gitea - ''; - }; - git-remote = { - repository = "rest:http://m1:8000/git"; - passwordFile = config.sops.secrets.restic-password.path; - initialize = true; - paths = [ "/var/lib/gitea/repositories" "/var/backup/git" ]; - backupPrepareCommand = '' - mkdir -p /var/backup/git - - ${pkgs.sudo}/bin/sudo ${pkgs.systemd}/bin/systemctl stop gitea - - ${pkgs.sudo}/bin/sudo -u postgres ${pkgs.postgresql}/bin/pg_dump \ - --clean \ - --if-exists \ - --dbname=git > /var/backup/git/postgres.sql - ''; - backupCleanupCommand = '' - ${pkgs.sudo}/bin/sudo ${pkgs.systemd}/bin/systemctl start gitea - ''; - }; - }; - - environment.systemPackages = with pkgs; - let - scripts = with pkgs; { - restore_git_pg = writeShellScriptBin "restore_git_pg" '' - ${pkgs.sudo}/bin/sudo -u postgres psql --dbname=git < /var/backup/git/postgres.sql - ''; - restore_git = writeShellScriptBin "restore_git" '' - ${pkgs.sudo}/bin/sudo ${pkgs.systemd}/bin/systemctl stop gitea - - ${pkgs.sudo}/bin/sudo ${restic}/bin/restic -r /mnt/hdd/restic/git restore latest --target / - - ${scripts.restore_git_pg}/bin/restore_git_pg - - ${pkgs.sudo}/bin/sudo ${pkgs.systemd}/bin/systemctl start gitea - ''; - }; - in [ scripts.restore_git_pg scripts.restore_git ]; -} diff --git a/host/ark/service/home.nix b/host/ark/service/home.nix deleted file mode 100644 index 85ed873..0000000 --- a/host/ark/service/home.nix +++ /dev/null @@ -1,28 +0,0 @@ -{ pkgs, ... }: { - virtualisation.oci-containers = let - hass_config = pkgs.writeText "configuration.yaml" '' - # Discovery - default_config: - - # Web Server configuration - http: - server_host: 127.0.0.1 - use_x_forwarded_for: true - trusted_proxies: 127.0.0.1 - ''; - in { - backend = "podman"; - containers.homeassistant = { - volumes = [ - "home-assistant:/config" - # "/data/docker/hass:/config" - "${hass_config}:/config/configuration.yaml" - # "/run/secrets/home-assistant:/config/secrets.yaml" - ]; - environment.TZ = "America/New_York"; - image = - "ghcr.io/home-assistant/home-assistant:stable"; # Warning: if the tag does not change, the image will not be updated - extraOptions = [ "--network=host" ]; - }; - }; -} diff --git a/host/ark/service/money.nix b/host/ark/service/money.nix deleted file mode 100644 index 0fc2d58..0000000 --- a/host/ark/service/money.nix +++ /dev/null @@ -1,199 +0,0 @@ -{ pkgs, config, ... }: - - let - - src = pkgs.fetchgit { - url = "https://git.koon.us/max/money.git"; - hash = "sha256-TPUeYuffR8U0M3Wnc3yGmqDhEjWIhRRFaKDkhTBsNG8="; - }; - - expoWeb = pkgs.stdenv.mkDerivation (finalAttrs: { - pname = "expo-web"; - version = "1.0.0"; - src = src; - pnpm = pkgs.pnpm_10; - nativeBuildInputs = [ - pkgs.nodejs - finalAttrs.pnpm.configHook - ]; - pnpmDeps = finalAttrs.pnpm.fetchDeps { - inherit (finalAttrs) pname version src; - fetcherVersion = 2; - hash = "sha256-x2zCFeMU0VfkVRILrLReEOFNrcd7aJp57v4fMGBE2dI="; - }; - pnpmInstallFlags = [ "--frozen-lockfile" ]; - buildPhase = '' - runHook preBuild - pnpm run build - runHook postBuild - ''; - - installPhase = '' - mkdir -p $out - cp -r dist/* $out/ - ''; - }); - - api = pkgs.stdenv.mkDerivation (finalAttrs: { - pname = "koon-money-api"; - version = "1.0.1"; - src = src; - pnpm = pkgs.pnpm_10; - nativeBuildInputs = [ - pkgs.nodejs - finalAttrs.pnpm.configHook - pkgs.python3 # Required for node-gyp - pkgs.nodePackages.node-gyp # For building native modules - pkgs.pkg-config - pkgs.gnumake - pkgs.gcc - ]; - buildInputs = [ - pkgs.sqlite - pkgs.sqlite.dev - pkgs.readline - pkgs.ncurses - pkgs.libbsd - ]; - pnpmDeps = finalAttrs.pnpm.fetchDeps { - inherit (finalAttrs) pname version src; - fetcherVersion = 2; - hash = "sha256-x2zCFeMU0VfkVRILrLReEOFNrcd7aJp57v4fMGBE2dI="; - }; - NIX_CFLAGS_COMPILE = "-D_GNU_SOURCE"; - pnpmInstallFlags = [ "--frozen-lockfile" ]; - - buildPhase = '' - runHook preBuild - cd node_modules/@rocicorp/zero-sqlite3 - node-gyp rebuild --build-from-source - cd - - runHook postBuild - ''; - - installPhase = '' - mkdir -p $out - cp -r . $out/ - ''; - }); - - api-port = "3161"; - in -{ - - services.nginx = { - enable = true; - - virtualHosts."money.koon.us" = { - root = "${expoWeb}"; - listen = [ - { addr = "127.0.0.1"; port = 3160; } - ]; - locations."/" = { - tryFiles = "$uri /index.html"; - }; - }; - - }; - - virtualisation.oci-containers = { - backend = "podman"; - containers = { - zero = { - image = "rocicorp/zero:0.23.2025101600"; - ports = ["127.0.0.1:4848:4848"]; - volumes = [ "/run/postgresql:/run/postgresql" ]; - environment = { - - ZERO_UPSTREAM_DB = "postgresql://postgres@127.0.0.1/money"; - ZERO_REPLICA_FILE = "/tmp/zync-replica.db"; - ZERO_GET_QUERIES_URL = "http://localhost:${api-port}/api/zero/get-queries"; - ZERO_GET_QUERIES_FORWARD_COOKIES = "true"; - - ZERO_MUTATE_URL = "http://localhost:${api-port}/api/zero/mutate"; - ZERO_MUTATE_FORWARD_COOKIES = "true"; - }; - extraOptions = [ "--network=host" ]; - }; - }; - }; - - services.postgresql = { - enable = true; - ensureDatabases = [ "money" ]; - ensureUsers = [ - { - name = "money"; - ensureDBOwnership = true; - } - ]; - authentication = '' - # TYPE DATABASE USER ADDRESS METHOD - local all postgres peer - host all all 127.0.0.1/32 trust - host all all ::1/128 trust - ''; - settings = { - wal_level = "logical"; - }; - }; - - systemd.services.money-api = { - description = "Money API"; - wantedBy = [ "multi-user.target" ]; - after = [ "network.target" ]; - - environment = { - ZERO_UPSTREAM_DB = "postgresql://postgres@127.0.0.1/money"; - PORT = api-port; - NODE_ENV = "production"; - BETTER_AUTH_SECRET = "burger"; - DEBUG = "*"; - NODE_OPTIONS = "--trace-warnings --trace-uncaught"; - OAUTH_DISCOVERY_URL = "https://auth.koon.us/.well-known/openid-configuration"; - PLAID_ENV = "production"; - }; - - serviceConfig = { - Type = "simple"; - User = "money"; - Group = "money"; - WorkingDirectory = "${api}/shared"; - - ExecStartPre = "${api}/node_modules/.bin/drizzle-kit push --config=${api}/shared/drizzle.config.ts"; - - ExecStart = pkgs.writeShellScript "money-api-start" '' - set -euo pipefail - - export OAUTH_CLIENT_ID="$(cat ${config.sops.secrets."money/clientId".path})" - export OAUTH_CLIENT_SECRET="$(cat ${config.sops.secrets."money/clientSecret".path})" - - exec ${api}/node_modules/.bin/tsx ${api}/api/src/index.ts - ''; - - EnvironmentFile = config.sops.secrets."money-env".path; - - Restart = "on-failure"; - RestartSec = 10; - - SyslogIdentifier = "money-api"; - StandardOutput = "journal"; - StandardError = "journal"; - }; - }; - - - - users.users.money = { - isSystemUser = true; - home = "/var/lib/money"; - createHome = true; - group = "money"; - }; - - users.groups.money = {}; - - - -} - diff --git a/host/ark/service/photos.nix b/host/ark/service/photos.nix deleted file mode 100644 index 89feb53..0000000 --- a/host/ark/service/photos.nix +++ /dev/null @@ -1,117 +0,0 @@ -{ lib, config, pkgs, ... }: { - sops = { - templates = { - "immich-config.json" = { - content = builtins.toJSON { - passwordLogin.enabled = false; - - # We will do this ourselves - backup.database.enabled = false; - - oauth = { - enabled = true; - autoLaunch = true; - autoRegister = true; - buttonText = - lib.strings.concatStrings [ "Login To " config.oauth.name ]; - clientId = config.sops.placeholder."photos/clientId"; - clientSecret = config.sops.placeholder."photos/clientSecret"; - issuerUrl = "https://auth.koon.us/.well-known/openid-configuration"; - }; - }; - owner = config.users.users.immich.name; - mode = "0400"; - restartUnits = [ "immich-server.service" "pocket-id.service" ]; - }; - }; - }; - - services.immich = { - enable = true; - port = 2283; - environment.IMMICH_CONFIG_FILE = config.sops.templates."immich-config.json".path; - accelerationDevices = null; - - machine-learning.environment = { - HF_XET_CACHE = "/var/cache/immich/huggingface-xet"; - }; - - }; - - users.users.immich = { - home = "/var/lib/immich"; - createHome = true; - extraGroups = [ "video" "render" ]; - }; - - hardware.graphics = { - enable = true; - extraPackages = with pkgs; [ intel-media-driver ]; - }; - environment.sessionVariables = { LIBVA_DRIVER_NAME = "iHD"; }; - - services.restic.backups = { - immich-local = { - repository = "/mnt/hdd/restic/immich"; - passwordFile = config.sops.secrets.restic-password.path; - initialize = true; - paths = [ "/var/lib/immich/upload" "/var/backup/immich" ]; - backupPrepareCommand = '' - mkdir -p /var/backup/immich - - ${pkgs.sudo}/bin/sudo ${pkgs.systemd}/bin/systemctl stop immich-server - ${pkgs.sudo}/bin/sudo ${pkgs.systemd}/bin/systemctl stop immich-machine-learning - - ${pkgs.sudo}/bin/sudo -u postgres ${pkgs.postgresql}/bin/pg_dump \ - --clean \ - --if-exists \ - --dbname=immich > /var/backup/immich/postgres.sql - ''; - backupCleanupCommand = '' - ${pkgs.sudo}/bin/sudo ${pkgs.systemd}/bin/systemctl start immich-server - ${pkgs.sudo}/bin/sudo ${pkgs.systemd}/bin/systemctl start immich-machine-learning - ''; - }; - immich-remote = { - repository = "rest:http://m1:8000/immich"; - passwordFile = config.sops.secrets.restic-password.path; - initialize = true; - paths = [ "/var/lib/immich/upload" "/var/backup/immich" ]; - backupPrepareCommand = '' - mkdir -p /var/backup/immich - - ${pkgs.sudo}/bin/sudo ${pkgs.systemd}/bin/systemctl stop immich-server - ${pkgs.sudo}/bin/sudo ${pkgs.systemd}/bin/systemctl stop immich-machine-learning - - ${pkgs.sudo}/bin/sudo -u postgres ${pkgs.postgresql}/bin/pg_dump \ - --clean \ - --if-exists \ - --dbname=immich > /var/backup/immich/postgres.sql - ''; - backupCleanupCommand = '' - ${pkgs.sudo}/bin/sudo ${pkgs.systemd}/bin/systemctl start immich-server - ${pkgs.sudo}/bin/sudo ${pkgs.systemd}/bin/systemctl start immich-machine-learning - ''; - }; - }; - - environment.systemPackages = with pkgs; - let - scripts = with pkgs; { - restore_immich_pg = writeShellScriptBin "restore_immich_pg" '' - ${pkgs.sudo}/bin/sudo -u postgres psql --dbname=immich < /var/backup/immich/postgres.sql - ''; - restore_immich = writeShellScriptBin "restore_immich" '' - ${pkgs.sudo}/bin/sudo ${pkgs.systemd}/bin/systemctl stop immich-server - ${pkgs.sudo}/bin/sudo ${pkgs.systemd}/bin/systemctl stop immich-machine-learning - - ${pkgs.sudo}/bin/sudo ${restic}/bin/restic -r /mnt/hdd/restic/immich restore latest --target / - - ${scripts.restore_immich_pg}/bin/restore_immich_pg - - ${pkgs.sudo}/bin/sudo ${pkgs.systemd}/bin/systemctl start immich-server - ${pkgs.sudo}/bin/sudo ${pkgs.systemd}/bin/systemctl start immich-machine-learning - ''; - }; - in [ scripts.restore_immich_pg scripts.restore_immich ]; -} diff --git a/host/ark/service/radicale.nix b/host/ark/service/radicale.nix deleted file mode 100644 index 0a5016e..0000000 --- a/host/ark/service/radicale.nix +++ /dev/null @@ -1,9 +0,0 @@ -{ ... }: { - services.radicale = { - enable = true; - settings = { - auth.type = "none"; - server.hosts = [ "0.0.0.0:5232" ]; - }; - }; -} diff --git a/host/ark/service/wakapi.nix b/host/ark/service/wakapi.nix deleted file mode 100644 index 8db67bf..0000000 --- a/host/ark/service/wakapi.nix +++ /dev/null @@ -1,50 +0,0 @@ -{ config, ... }: -{ - - nixpkgs.overlays = [ - (final: prev: let - version = "2.15.0"; - in { - - wakapi = (prev.buildGoModule.override { go = prev.go_1_25; }) { - pname = "wakapi"; - version = version; - - src = final.fetchFromGitHub { - owner = "k2on"; - repo = "wakapi"; - rev = "koon-fork"; - hash = "sha256-FYGtoJmbqUD02/JKvON1RqpjkrDkAOkfPwMAUZ2MSE4="; - }; - - vendorHash = "sha256-912x6LwitYXdjWpP75Xoc56JXadeLQZuESSyLoaJcU0="; - - excludedPackages = [ "scripts" ]; - - postPatch = ''echo ${version} > version.txt''; - - ldflags = [ "-s" "-w" ]; - - passthru = { - nixos = prev.nixosTests.wakapi; - updateScript = prev.nix-update-script { }; - }; - - meta = prev.wakapi.meta // { - version = version; - mainProgram = "wakapi"; - }; - }; - - }) - ]; - - services.wakapi = { - enable = true; - passwordSaltFile = config.sops.secrets."waka-password-salt".path; - settings = { - server.port = 3006; - app.avatar_url_template = "https://auth.koon.us/api/users/fbffa48a-faf7-4230-a89f-0da184f5948c/profile-picture.png"; - }; - }; -} diff --git a/host/ark/sops.nix b/host/ark/sops.nix deleted file mode 100644 index e615980..0000000 --- a/host/ark/sops.nix +++ /dev/null @@ -1,69 +0,0 @@ -{ config, ... }: -{ - sops = { - - defaultSopsFile = ../../secrets/sops/host/ark/default.yaml; - validateSopsFiles = false; - - age.keyFile = if builtins.pathExists /var/lib/sops-nix/key.txt then - "/var/lib/sops-nix/key.txt" - else - "/home/admin/.config/sops/age/keys.txt" # temp decrypt key - ; - - secrets = { - "host_age_key" = { - path = "/var/lib/sops-nix/key.txt"; - }; - - "restic-password" = {}; - "tunnel-credentials" = {}; - "admin-password" = {}; - - "pocket-id-encryption-key" = { - owner = config.services.pocket-id.user; - }; - - "waka-password-salt" = { - owner = config.users.users.wakapi.name; - }; - - "money-env" = { - owner = config.users.users.money.name; - }; - - "photos/clientId" = { - sopsFile = ../../secrets/sops/host/ark/oauth.yaml; - }; - "photos/clientSecret" = { - sopsFile = ../../secrets/sops/host/ark/oauth.yaml; - }; - - "git/clientId" = { - sopsFile = ../../secrets/sops/host/ark/oauth.yaml; - owner = config.services.gitea.user; - }; - "git/clientSecret" = { - sopsFile = ../../secrets/sops/host/ark/oauth.yaml; - owner = config.services.gitea.user; - }; - - "docs/clientId" = { - sopsFile = ../../secrets/sops/host/ark/oauth.yaml; - owner = config.services.outline.user; - }; - "docs/clientSecret" = { - sopsFile = ../../secrets/sops/host/ark/oauth.yaml; - owner = config.services.outline.user; - }; - "money/clientId" = { - sopsFile = ../../secrets/sops/host/ark/oauth.yaml; - owner = config.users.users.money.name; - }; - "money/clientSecret" = { - sopsFile = ../../secrets/sops/host/ark/oauth.yaml; - owner = config.users.users.money.name; - }; - }; - }; -} diff --git a/host/ark/user.nix b/host/ark/user.nix deleted file mode 100644 index bcf2d5a..0000000 --- a/host/ark/user.nix +++ /dev/null @@ -1,12 +0,0 @@ -{ pkgs, config, ... }: { - - sops.secrets.admin-password.neededForUsers = true; - users.mutableUsers = false; - - users.users.admin = { - isNormalUser = true; - extraGroups = [ "wheel" ]; - hashedPasswordFile = config.sops.secrets.admin-password.path; - packages = with pkgs; [ tree vim tmux restic ]; - }; -} diff --git a/host/max/default.nix b/host/max/default.nix deleted file mode 100644 index c391bbd..0000000 --- a/host/max/default.nix +++ /dev/null @@ -1,145 +0,0 @@ -{ pkgs, pkgs-unstable, ... }: -{ - imports = [ - ./hardware-configuration.nix - ../common/core/default.nix - ./user.nix - ./work.nix - ./sops.nix - ./tailscale.nix - - ../common/optional/desktop/hyprland.nix - ../common/optional/font.nix - ../common/optional/yubikey.nix - ../common/optional/browser.nix - ../common/optional/locale.nix - ../common/optional/email.nix - ../common/optional/proton.nix - ]; - - # Use the systemd-boot EFI boot loader. - boot.loader.systemd-boot.enable = true; - boot.loader.efi.canTouchEfiVariables = false; - - boot.m1n1CustomLogo = ../../assets/logo.png; - - hardware = { - asahi = { - peripheralFirmwareDirectory = ./firmware; - setupAsahiSound = true; - }; - }; - - hardware.opengl = { - enable = true; - extraPackages = with pkgs; [ - mesa.opencl - ]; - }; - - services.upower.enable = true; - services.logind.settings.Login.HandlePowerKey = "ignore"; - - networking.networkmanager = { - enable = true; - plugins = with pkgs; [ - networkmanager-openconnect - ]; - }; - - hardware.bluetooth = { - enable = true; - powerOnBoot = true; - }; - - environment.variables = { - XDG_DATA_HOME = "/home/max/.local/share"; - GSK_RENDERER = "ngl"; - EDITOR = "nvim"; - }; - environment.sessionVariables.NIXOS_OZONE_WL = "1"; - - programs.kdeconnect.enable = true; - - environment.systemPackages = with pkgs; [ - networkmanager - - vim - git - wget - file - just - - libreoffice-qt - - pkgs-unstable.signal-desktop - pkgs-unstable.gurk-rs - - gnupg - - (pass.withExtensions (exts: [ exts.pass-otp ])) - - pinentry-curses - pinentry-qt - - fzf - zip - jq - ffmpeg - ripgrep - unzip - zbar - tt - sc-im - libqalculate - librespeed-cli - - gparted - - tea - - cloudflared - # gcc - - prismlauncher - - gimp - inkscape - - # arm support - pkgs-unstable.sparrow - - - (writeShellScriptBin "radio" '' - list=" - WIOP http://s4.yesstreaming.net:7119/;audio.mp3 - FamilyAlter https://usa17.fastcast4u.com/proxy/roloffev?mp=/1 - " - - choice=$(echo "$list" | awk '{print $1}' | ${fzf}/bin/fzf) - - if [[ -n "$choice" ]]; then - url=$(echo "$list" | awk -v name="$choice" '$1==name {print $2}') - ${mpg123}/bin/mpg123 "$url" - fi - '') - - (pkgs.writeShellScriptBin "battery-graph" '' - ${pkgs.coreutils}/bin/tail -n 20 /var/lib/upower/history-charge-bq40z651-69-F8Y3262H468Q1LTA1.dat | ${pkgs.coreutils}/bin/cut -f1,2 | RUBYOPT='-W0' ${pkgs.youplot}/bin/uplot line -w 70 - '') - - (pkgs.writeShellScriptBin "ocr-clip" '' - ${pkgs.grimblast}/bin/grimblast -f save area - | ${pkgs.tesseract}/bin/tesseract stdin stdout | ${pkgs.wl-clipboard}/bin/wl-copy - '') - ]; - - programs.zsh.enable = true; - - programs.gnupg.agent = { - enable = true; - pinentryPackage = pkgs.pinentry-qt; - enableSSHSupport = true; - }; - - system.stateVersion = "25.05"; -} diff --git a/host/max/home.nix b/host/max/home.nix deleted file mode 100644 index 5ea1c9b..0000000 --- a/host/max/home.nix +++ /dev/null @@ -1,28 +0,0 @@ -{ ... }: - -{ - imports = [ - ./home/sops.nix - ./home/ssh.nix - ./home/git.nix - - ./home/browser.nix - ./home/image-viewer.nix - - ../../home/common/optional/desktop/hyprland.nix - - ./home/nvim.nix - ./home/terminal.nix - ./home/zathura.nix - ./home/music.nix - ]; - - gtk = { - enable = true; - colorScheme = "dark"; - }; - - home.username = "max"; - home.homeDirectory = "/home/max"; - home.stateVersion = "25.05"; -} diff --git a/justfile b/justfile index 0ce79d0..0af2ebd 100644 --- a/justfile +++ b/justfile @@ -29,7 +29,14 @@ rebuild-ark: just add-secrets git add . - nixos-rebuild --flake '.?submodules=1#ark' --build-host admin@192.168.1.192 --target-host admin@192.168.1.192 --use-remote-sudo --fast switch + nixos-rebuild --flake '.?submodules=1#koonArk' --build-host ark --target-host ark --use-remote-sudo --fast switch + + +rebuild-ark-boot: + just add-secrets + + git add . + nixos-rebuild --flake '.?submodules=1#koonArk' --build-host ark --target-host ark --use-remote-sudo --fast boot push-secrets: just add-secrets diff --git a/modules/common/features/hyprland/wallpaper.nix b/modules/common/features/hyprland/wallpaper.nix index 7b8db35..89cfcef 100644 --- a/modules/common/features/hyprland/wallpaper.nix +++ b/modules/common/features/hyprland/wallpaper.nix @@ -1,7 +1,7 @@ { self, ... }: { flake.homeModules.commonFeatureWallpaper = { ... }: let - wallpaper = builtins.toString "${self}/assets/wallpaper2.jpg"; + wallpaper = builtins.toString "${self}/assets/wallpaper.jpg"; in { services.hyprpaper = { enable = true; diff --git a/host/ark/hardware-configuration.nix b/modules/koon/host/ark/_hardware-configuration.nix similarity index 100% rename from host/ark/hardware-configuration.nix rename to modules/koon/host/ark/_hardware-configuration.nix diff --git a/modules/koon/host/ark/configuration.nix b/modules/koon/host/ark/configuration.nix new file mode 100644 index 0000000..72c27e4 --- /dev/null +++ b/modules/koon/host/ark/configuration.nix @@ -0,0 +1,77 @@ +{ self, ... }: { + flake.nixosModules.koonArkConfiguration = { config, ... }: { + imports = [ + ./_hardware-configuration.nix + self.nixosModules.koonArkUser + self.nixosModules.koonArkSops + + self.nixosModules.koonArkServiceAudio + self.nixosModules.koonArkServiceAuth + self.nixosModules.koonArkServiceGit + self.nixosModules.koonArkServiceHome + self.nixosModules.koonArkServicePhotos + self.nixosModules.koonArkServiceRadicale + self.nixosModules.koonArkServiceWakapi + ]; + + # Use the systemd-boot EFI boot loader. + boot.loader.systemd-boot.enable = true; + boot.loader.efi.canTouchEfiVariables = true; + + networking.hostName = "ark"; + networking.nameservers = [ "8.8.8.8" "1.1.1.1" ]; + + services.tailscale = { + enable = true; + useRoutingFeatures = "both"; + extraUpFlags = [ "--accept-dns=false" ]; + }; + + # oauth.name = "KoonFamily"; + # oauth.secrets = import ./oauth-secrets.nix; + + security.sudo.wheelNeedsPassword = false; + + services.cloudflared = { + enable = true; + tunnels = { + "91d31395-fbc7-45a1-ae13-148957b32ecd" = { + credentialsFile = config.sops.secrets.tunnel-credentials.path; + ingress = { + "auth.koon.us" = "http://localhost:1411"; + "photos.koon.us" = "http://localhost:2283"; + "home.koon.us" = "http://localhost:8123"; + "docs.koon.us" = "http://localhost:3004"; + "git.koon.us" = "http://localhost:3000"; + "ssh.koon.us" = "ssh://localhost:2222"; + "audio.koon.us" = "http://localhost:8021"; + "radicale.koon.us" = "http://localhost:5232"; + "waka.koon.us" = "http://localhost:3006"; + # "ride.koon.us" = "http://localhost:3007"; + # "ride-api.koon.us" = "http://localhost:8080"; + + "money.koon.us" = "http://localhost:3160"; + "zero.koon.us" = "http://localhost:4848"; + "money-api.koon.us" = "http://localhost:3161"; + + }; + default = "http_status:404"; + }; + }; + }; + + fileSystems."/mnt/hdd" = { + device = "/dev/sdb"; + fsType = "ext4"; + }; + + services.openssh.enable = true; + + networking.firewall.allowedTCPPorts = [ 8123 22 ]; + + time.timeZone = "America/New_York"; + nix.settings.experimental-features = [ "nix-command" "flakes" ]; + + system.stateVersion = "25.05"; # Did you read the comment? + }; +} diff --git a/modules/koon/host/ark/default.nix b/modules/koon/host/ark/default.nix new file mode 100644 index 0000000..e62d473 --- /dev/null +++ b/modules/koon/host/ark/default.nix @@ -0,0 +1,8 @@ +{ self, inputs, ... }: { + flake.nixosConfigurations.koonArk = inputs.nixpkgs-unstable.lib.nixosSystem { + modules = [ + self.inputs.sops-nix.nixosModules.sops + self.nixosModules.koonArkConfiguration + ]; + }; +} diff --git a/modules/koon/host/ark/service/audio.nix b/modules/koon/host/ark/service/audio.nix new file mode 100644 index 0000000..3955334 --- /dev/null +++ b/modules/koon/host/ark/service/audio.nix @@ -0,0 +1,8 @@ +{ ... }: { + flake.nixosModules.koonArkServiceAudio = { ... }: { + services.audiobookshelf = { + enable = true; + port = 8021; + }; + }; +} diff --git a/modules/koon/host/ark/service/auth.nix b/modules/koon/host/ark/service/auth.nix new file mode 100644 index 0000000..77f8e3f --- /dev/null +++ b/modules/koon/host/ark/service/auth.nix @@ -0,0 +1,21 @@ +{ ... }: { + flake.nixosModules.koonArkServiceAuth = { config, ... }: { + services.pocket-id = { + enable = true; + settings = { + APP_URL = "https://auth.koon.us"; + TRUST_PROXY = true; + ANALYTICS_DISABLED = true; + + UI_CONFIG_DISABLED = true; + + APP_NAME = "KoonFamily"; + }; + + credentials = { + ENCRYPTION_KEY = config.sops.secrets."pocket-id-encryption-key".path; + }; + }; + }; +} + diff --git a/modules/koon/host/ark/service/git.nix b/modules/koon/host/ark/service/git.nix new file mode 100644 index 0000000..0645f1d --- /dev/null +++ b/modules/koon/host/ark/service/git.nix @@ -0,0 +1,193 @@ +{ ... }: { + flake.nixosModules.koonArkServiceGit = { config, lib, pkgs, ... }: + let + oauthName = "KoonFamily"; + in { + services.openssh = { + enable = true; + + # hostKeys = [ + # { path = "/etc/ssh/ssh_host_ed25519_key"; type = "ed25519"; } + # { path = "/etc/ssh/ssh_host_rsa_key"; type = "rsa"; bits = 4096; } + # ]; + + settings = { + # explicitly allow post-quantum KEX + KexAlgorithms = [ + "mlkem768x25519-sha256" + "sntrup761x25519-sha512" + "curve25519-sha256" + ]; + }; + }; + + services.gitea = { + enable = true; + user = "git"; + group = "git"; + database = { + user = "git"; + name = "git"; + type = "postgres"; + }; + settings = { + server = { + DOMAIN = "git.koon.us"; + ROOT_URL = "https://git.koon.us"; + HTTP_PORT = 3000; + LANDING_PAGE = "/max"; + SSH_DOMAIN = "ssh.koon.us"; + SSH_PORT = 2222; + START_SSH_SERVER = true; + }; + oauth2_client = { + ACCOUNT_LINKING = "auto"; + ENABLE_AUTO_REGISTRATION = true; + UPDATE_AVATAR = true; + USERNAME = "email"; + }; + service = { + DISABLE_REGISTRATION = true; + ENABLE_PASSWORD_SIGNIN_FORM = false; + ENABLE_PASSKEY_AUTHENTICATION = false; + + SHOW_MILESTONES_DASHBOARD_PAGE = false; + }; + "service.explore" = { + DISABLE_USERS_PAGE = true; + DISABLE_ORGANIZATIONS_PAGE = true; + DISABLE_CODE_PAGE = true; + }; + }; + }; + + users.users.git = { + isSystemUser = true; + group = "git"; + home = "/var/lib/gitea"; + description = "Git server (Gitea)"; + createHome = true; + }; + users.groups.git = { }; + + systemd.services.gitea = { + serviceConfig = { + RestartSec = "60"; # Retry every minute + }; + preStart = let + exe = lib.getExe config.services.gitea.package; + + clientIdPath = config.sops.secrets."oauth/git/clientId".path; + clientSecretPath = config.sops.secrets."oauth/git/clientSecret".path; + + args = lib.escapeShellArgs (lib.concatLists [ + [ "--name" oauthName ] + [ "--provider" "openidConnect" ] + # [ "--key" config.oauth.secrets.git.clientId ] + [ + "--auto-discover-url" + "https://auth.koon.us/.well-known/openid-configuration" + ] + [ "--scopes" "email" ] + [ "--scopes" "profile" ] + [ "--group-claim-name" "groups" ] + [ "--admin-group" "admin" ] + [ "--skip-local-2fa" ] + ]); + in lib.mkAfter '' + CLIENT_ID=$(cat ${clientIdPath}) + CLIENT_SECRET=$(cat ${clientSecretPath}) + + provider_id=$(${exe} admin auth list | ${pkgs.gnugrep}/bin/grep -w '${oauthName}' | cut -f1) + + if [[ -z "$provider_id" ]]; then + ${exe} admin auth add-oauth ${args} --key "$CLIENT_ID" --secret "$CLIENT_SECRET" + else + ${exe} admin auth update-oauth --id "$provider_id" ${args} --key "$CLIENT_ID" --secret "$CLIENT_SECRET" + fi + + mkdir -p /var/lib/gitea/custom/public/assets/img/ + + ln -sf ${ + ./git/assets/img/logo.svg + } /var/lib/gitea/custom/public/assets/img/logo.svg + ln -sf ${ + ./git/assets/img/favicon.svg + } /var/lib/gitea/custom/public/assets/img/favicon.svg + + mkdir -p /var/lib/gitea/custom/templates/base/ + ln -sf ${ + ./git/templates/base/head_navbar.tmpl + } /var/lib/gitea/custom/templates/base/head_navbar.tmpl + ln -sf ${ + ./git/templates/base/footer_content.tmpl + } /var/lib/gitea/custom/templates/base/footer_content.tmpl + + mkdir -p /var/lib/gitea/custom/templates/custom/ + ln -sf ${ + ./git/templates/custom/header.tmpl + } /var/lib/gitea/custom/templates/custom/header.tmpl + + ''; + }; + + services.restic.backups = { + git-local = { + repository = "/mnt/hdd/restic/git"; + passwordFile = config.sops.secrets.restic-password.path; + initialize = true; + paths = [ "/var/lib/gitea/repositories" "/var/backup/git" ]; + backupPrepareCommand = '' + mkdir -p /var/backup/git + + ${pkgs.sudo}/bin/sudo ${pkgs.systemd}/bin/systemctl stop gitea + + ${pkgs.sudo}/bin/sudo -u postgres ${pkgs.postgresql}/bin/pg_dump \ + --clean \ + --if-exists \ + --dbname=git > /var/backup/git/postgres.sql + ''; + backupCleanupCommand = '' + ${pkgs.sudo}/bin/sudo ${pkgs.systemd}/bin/systemctl start gitea + ''; + }; + git-remote = { + repository = "rest:http://m1:8000/git"; + passwordFile = config.sops.secrets.restic-password.path; + initialize = true; + paths = [ "/var/lib/gitea/repositories" "/var/backup/git" ]; + backupPrepareCommand = '' + mkdir -p /var/backup/git + + ${pkgs.sudo}/bin/sudo ${pkgs.systemd}/bin/systemctl stop gitea + + ${pkgs.sudo}/bin/sudo -u postgres ${pkgs.postgresql}/bin/pg_dump \ + --clean \ + --if-exists \ + --dbname=git > /var/backup/git/postgres.sql + ''; + backupCleanupCommand = '' + ${pkgs.sudo}/bin/sudo ${pkgs.systemd}/bin/systemctl start gitea + ''; + }; + }; + + environment.systemPackages = with pkgs; + let + scripts = with pkgs; { + restore_git_pg = writeShellScriptBin "restore_git_pg" '' + ${pkgs.sudo}/bin/sudo -u postgres psql --dbname=git < /var/backup/git/postgres.sql + ''; + restore_git = writeShellScriptBin "restore_git" '' + ${pkgs.sudo}/bin/sudo ${pkgs.systemd}/bin/systemctl stop gitea + + ${pkgs.sudo}/bin/sudo ${restic}/bin/restic -r /mnt/hdd/restic/git restore latest --target / + + ${scripts.restore_git_pg}/bin/restore_git_pg + + ${pkgs.sudo}/bin/sudo ${pkgs.systemd}/bin/systemctl start gitea + ''; + }; + in [ scripts.restore_git_pg scripts.restore_git ]; + }; +} diff --git a/host/ark/service/git/assets/css/custom.css b/modules/koon/host/ark/service/git/assets/css/custom.css similarity index 100% rename from host/ark/service/git/assets/css/custom.css rename to modules/koon/host/ark/service/git/assets/css/custom.css diff --git a/host/ark/service/git/assets/img/favicon.svg b/modules/koon/host/ark/service/git/assets/img/favicon.svg similarity index 100% rename from host/ark/service/git/assets/img/favicon.svg rename to modules/koon/host/ark/service/git/assets/img/favicon.svg diff --git a/host/ark/service/git/assets/img/logo.svg b/modules/koon/host/ark/service/git/assets/img/logo.svg similarity index 100% rename from host/ark/service/git/assets/img/logo.svg rename to modules/koon/host/ark/service/git/assets/img/logo.svg diff --git a/host/ark/service/git/templates/base/footer_content.tmpl b/modules/koon/host/ark/service/git/templates/base/footer_content.tmpl similarity index 100% rename from host/ark/service/git/templates/base/footer_content.tmpl rename to modules/koon/host/ark/service/git/templates/base/footer_content.tmpl diff --git a/host/ark/service/git/templates/base/head_navbar.tmpl b/modules/koon/host/ark/service/git/templates/base/head_navbar.tmpl similarity index 100% rename from host/ark/service/git/templates/base/head_navbar.tmpl rename to modules/koon/host/ark/service/git/templates/base/head_navbar.tmpl diff --git a/host/ark/service/git/templates/custom/header.tmpl b/modules/koon/host/ark/service/git/templates/custom/header.tmpl similarity index 100% rename from host/ark/service/git/templates/custom/header.tmpl rename to modules/koon/host/ark/service/git/templates/custom/header.tmpl diff --git a/modules/koon/host/ark/service/home.nix b/modules/koon/host/ark/service/home.nix new file mode 100644 index 0000000..07139a9 --- /dev/null +++ b/modules/koon/host/ark/service/home.nix @@ -0,0 +1,38 @@ +{ ... }: { + flake.nixosModules.koonArkServiceHome = { pkgs, ... }: { + + virtualisation.oci-containers = let + hass_config = pkgs.writeText "configuration.yaml" '' + # Discovery + default_config: + + # Web Server configuration + http: + server_host: 127.0.0.1 + use_x_forwarded_for: true + trusted_proxies: 127.0.0.1 + sonos: + media_player: + hosts: + - 10.0.0.77 + - 10.0.0.186 + ''; + in { + backend = "podman"; + containers.homeassistant = { + volumes = [ + "home-assistant:/config" + # "/data/docker/hass:/config" + "${hass_config}:/config/configuration.yaml" + # "/run/secrets/home-assistant:/config/secrets.yaml" + ]; + environment.TZ = "America/New_York"; + image = + "ghcr.io/home-assistant/home-assistant:stable"; # Warning: if the tag does not change, the image will not be updated + extraOptions = [ "--network=host" ]; + }; + }; + + networking.firewall.allowedTCPPorts = [ 1400 ]; + }; +} diff --git a/modules/koon/host/ark/service/photos.nix b/modules/koon/host/ark/service/photos.nix new file mode 100644 index 0000000..2fcbc18 --- /dev/null +++ b/modules/koon/host/ark/service/photos.nix @@ -0,0 +1,123 @@ +{ ... }: { + flake.nixosModules.koonArkServicePhotos = { config, lib, pkgs, ... }: + let + oauthName = "KoonFamily"; + in { + sops = { + templates = { + "immich-config.json" = { + content = builtins.toJSON { + passwordLogin.enabled = false; + + # We will do this ourselves + backup.database.enabled = false; + + oauth = { + enabled = true; + autoLaunch = true; + autoRegister = true; + buttonText = + lib.strings.concatStrings [ "Login To " oauthName ]; + clientId = config.sops.placeholder."oauth/photos/clientId"; + clientSecret = config.sops.placeholder."oauth/photos/clientSecret"; + issuerUrl = "https://auth.koon.us/.well-known/openid-configuration"; + }; + }; + owner = config.users.users.immich.name; + mode = "0400"; + restartUnits = [ "immich-server.service" "pocket-id.service" ]; + }; + }; + }; + + services.immich = { + enable = true; + port = 2283; + environment.IMMICH_CONFIG_FILE = config.sops.templates."immich-config.json".path; + accelerationDevices = null; + + machine-learning.environment = { + HF_XET_CACHE = "/var/cache/immich/huggingface-xet"; + }; + + }; + + users.users.immich = { + home = "/var/lib/immich"; + createHome = true; + extraGroups = [ "video" "render" ]; + }; + + hardware.graphics = { + enable = true; + extraPackages = with pkgs; [ intel-media-driver ]; + }; + environment.sessionVariables = { LIBVA_DRIVER_NAME = "iHD"; }; + + services.restic.backups = { + immich-local = { + repository = "/mnt/hdd/restic/immich"; + passwordFile = config.sops.secrets.restic-password.path; + initialize = true; + paths = [ "/var/lib/immich/upload" "/var/backup/immich" ]; + backupPrepareCommand = '' + mkdir -p /var/backup/immich + + ${pkgs.sudo}/bin/sudo ${pkgs.systemd}/bin/systemctl stop immich-server + ${pkgs.sudo}/bin/sudo ${pkgs.systemd}/bin/systemctl stop immich-machine-learning + + ${pkgs.sudo}/bin/sudo -u postgres ${pkgs.postgresql}/bin/pg_dump \ + --clean \ + --if-exists \ + --dbname=immich > /var/backup/immich/postgres.sql + ''; + backupCleanupCommand = '' + ${pkgs.sudo}/bin/sudo ${pkgs.systemd}/bin/systemctl start immich-server + ${pkgs.sudo}/bin/sudo ${pkgs.systemd}/bin/systemctl start immich-machine-learning + ''; + }; + immich-remote = { + repository = "rest:http://m1:8000/immich"; + passwordFile = config.sops.secrets.restic-password.path; + initialize = true; + paths = [ "/var/lib/immich/upload" "/var/backup/immich" ]; + backupPrepareCommand = '' + mkdir -p /var/backup/immich + + ${pkgs.sudo}/bin/sudo ${pkgs.systemd}/bin/systemctl stop immich-server + ${pkgs.sudo}/bin/sudo ${pkgs.systemd}/bin/systemctl stop immich-machine-learning + + ${pkgs.sudo}/bin/sudo -u postgres ${pkgs.postgresql}/bin/pg_dump \ + --clean \ + --if-exists \ + --dbname=immich > /var/backup/immich/postgres.sql + ''; + backupCleanupCommand = '' + ${pkgs.sudo}/bin/sudo ${pkgs.systemd}/bin/systemctl start immich-server + ${pkgs.sudo}/bin/sudo ${pkgs.systemd}/bin/systemctl start immich-machine-learning + ''; + }; + }; + + environment.systemPackages = with pkgs; + let + scripts = with pkgs; { + restore_immich_pg = writeShellScriptBin "restore_immich_pg" '' + ${pkgs.sudo}/bin/sudo -u postgres psql --dbname=immich < /var/backup/immich/postgres.sql + ''; + restore_immich = writeShellScriptBin "restore_immich" '' + ${pkgs.sudo}/bin/sudo ${pkgs.systemd}/bin/systemctl stop immich-server + ${pkgs.sudo}/bin/sudo ${pkgs.systemd}/bin/systemctl stop immich-machine-learning + + ${pkgs.sudo}/bin/sudo ${restic}/bin/restic -r /mnt/hdd/restic/immich restore latest --target / + + ${scripts.restore_immich_pg}/bin/restore_immich_pg + + ${pkgs.sudo}/bin/sudo ${pkgs.systemd}/bin/systemctl start immich-server + ${pkgs.sudo}/bin/sudo ${pkgs.systemd}/bin/systemctl start immich-machine-learning + ''; + }; + in [ scripts.restore_immich_pg scripts.restore_immich ]; + + }; +} diff --git a/modules/koon/host/ark/service/radicale.nix b/modules/koon/host/ark/service/radicale.nix new file mode 100644 index 0000000..d9b2664 --- /dev/null +++ b/modules/koon/host/ark/service/radicale.nix @@ -0,0 +1,11 @@ +{ ... }: { + flake.nixosModules.koonArkServiceRadicale = { ... }: { + services.radicale = { + enable = true; + settings = { + auth.type = "none"; + server.hosts = [ "0.0.0.0:5232" ]; + }; + }; + }; +} diff --git a/modules/koon/host/ark/service/wakapi.nix b/modules/koon/host/ark/service/wakapi.nix new file mode 100644 index 0000000..1139ee7 --- /dev/null +++ b/modules/koon/host/ark/service/wakapi.nix @@ -0,0 +1,50 @@ +{ ... }: { + flake.nixosModules.koonArkServiceWakapi = { config, ... }: { + nixpkgs.overlays = [ + (final: prev: let + version = "2.15.0"; + in { + + wakapi = (prev.buildGoModule.override { go = prev.go_1_25; }) { + pname = "wakapi"; + version = version; + + src = final.fetchFromGitHub { + owner = "k2on"; + repo = "wakapi"; + rev = "koon-fork"; + hash = "sha256-FYGtoJmbqUD02/JKvON1RqpjkrDkAOkfPwMAUZ2MSE4="; + }; + + vendorHash = "sha256-912x6LwitYXdjWpP75Xoc56JXadeLQZuESSyLoaJcU0="; + + excludedPackages = [ "scripts" ]; + + postPatch = ''echo ${version} > version.txt''; + + ldflags = [ "-s" "-w" ]; + + passthru = { + nixos = prev.nixosTests.wakapi; + updateScript = prev.nix-update-script { }; + }; + + meta = prev.wakapi.meta // { + version = version; + mainProgram = "wakapi"; + }; + }; + + }) + ]; + + services.wakapi = { + enable = true; + # passwordSaltFile = config.sops.secrets."waka-password-salt".path; + settings = { + server.port = 3006; + app.avatar_url_template = "https://auth.koon.us/api/users/fbffa48a-faf7-4230-a89f-0da184f5948c/profile-picture.png"; + }; + }; + }; +} diff --git a/modules/koon/host/ark/sops.nix b/modules/koon/host/ark/sops.nix new file mode 100644 index 0000000..80e5e0f --- /dev/null +++ b/modules/koon/host/ark/sops.nix @@ -0,0 +1,34 @@ +{ self, ... }: { + flake.nixosModules.koonArkSops = { config, ... }: { + sops = { + age.sshKeyPaths = [ "/etc/ssh/ssh_host_ed25519_key" ]; + + defaultSopsFile = "${self}/secrets/koon/ark/default.yaml"; + + validateSopsFiles = false; + + secrets = { + "restic-password" = {}; + "tunnel-credentials" = {}; + "admin-password" = {}; + + "pocket-id-encryption-key" = { + owner = config.services.pocket-id.user; + }; + + "waka-password-salt" = { + owner = config.users.users.wakapi.name; + }; + + "oauth/photos/clientId" = {}; + "oauth/photos/clientSecret" = {}; + "oauth/git/clientId" = { + owner = config.services.gitea.user; + }; + "oauth/git/clientSecret" = { + owner = config.services.gitea.user; + }; + }; + }; + }; +} diff --git a/modules/koon/host/ark/user.nix b/modules/koon/host/ark/user.nix new file mode 100644 index 0000000..78ca1cb --- /dev/null +++ b/modules/koon/host/ark/user.nix @@ -0,0 +1,13 @@ +{ ... }: { + flake.nixosModules.koonArkUser = { pkgs, config, ... }: { + sops.secrets.admin-password.neededForUsers = true; + users.mutableUsers = false; + + users.users.admin = { + isNormalUser = true; + extraGroups = [ "wheel" ]; + hashedPasswordFile = config.sops.secrets.admin-password.path; + packages = with pkgs; [ tree vim tmux restic ]; + }; + }; +} diff --git a/modules/koon/host/max/default.nix b/modules/koon/host/max/default.nix index c1e0bc2..a834a82 100644 --- a/modules/koon/host/max/default.nix +++ b/modules/koon/host/max/default.nix @@ -8,4 +8,3 @@ ]; }; } - diff --git a/secrets b/secrets index c4f9e7b..30499ac 160000 --- a/secrets +++ b/secrets @@ -1 +1 @@ -Subproject commit c4f9e7bd9888dc3f3c078408e335004ffe8c5a92 +Subproject commit 30499ac6229fcf40c63a4298ab2de26c987c1867