diff --git a/containers/emerald/flake.nix b/containers/emerald/flake.nix index 5ee69e4..38a52b2 100644 --- a/containers/emerald/flake.nix +++ b/containers/emerald/flake.nix @@ -39,7 +39,7 @@ useACMEHost = "lava.moe"; forceSSL = true; locations."/".proxyPass = "http://[${client}]:4533"; - listenAddresses = [ "100.67.2.1" ]; + listenAddresses = config.me.localAddrs; }; systemd.tmpfiles.rules = [ "d /persist/containers/${name} 755 root users" ]; diff --git a/hosts/alyssum/default.nix b/hosts/alyssum/default.nix index 06c415f..eedcc2c 100644 --- a/hosts/alyssum/default.nix +++ b/hosts/alyssum/default.nix @@ -33,9 +33,12 @@ ./filesystem.nix ./kernel.nix - ./networking.nix ./home.syncthing.nix + ./immich.nix + ./networking.nix + ./restic.nix ./samba.nix + ./snapper.nix ../../users/hana ]; diff --git a/hosts/alyssum/filesystem.nix b/hosts/alyssum/filesystem.nix index bdea423..c40d2b2 100644 --- a/hosts/alyssum/filesystem.nix +++ b/hosts/alyssum/filesystem.nix @@ -1,4 +1,4 @@ -{ ... }: +{ gcSecrets, ... }: let bind = src: { depends = [ "/nix" ]; @@ -32,4 +32,6 @@ in { "/persist/.snapshots" = submount "/snap/persist" false; "/var/log/journal" = bind "/persist/journal"; }; + + me.binds."${gcSecrets.binds."navi/1a"}" = gcSecrets.binds."navi/1b"; } diff --git a/hosts/alyssum/immich.nix b/hosts/alyssum/immich.nix new file mode 100644 index 0000000..06515bb --- /dev/null +++ b/hosts/alyssum/immich.nix @@ -0,0 +1,37 @@ +{ config, gcSecrets, ... }: +let + fqdn = "photos.lava.moe"; + shareFqdn = "memo.lava.moe"; +in { + services.immich = { + enable = true; + accelerationDevices = null; + settings.server.externalDomain = "https://${shareFqdn}"; + }; + + me.binds."/var/lib/immich" = "/flower/immich"; + me.binds."/var/lib/immich/encoded-video" = "immich/encoded-video"; + me.binds."/var/lib/immich/profile" = "immich/profile"; + me.binds."/var/lib/immich/thumbs" = "immich/thumbs"; + me.binds."/mnt/immich_external/1/1" = gcSecrets.binds."immich/external/1/1"; + me.binds."/mnt/immich_external/1/2" = gcSecrets.binds."immich/external/1/2"; + hardware.graphics.enable = true; + users.users.immich.extraGroups = [ "video" "render" ]; + + services.nginx.virtualHosts."${fqdn}" = { + useACMEHost = "lava.moe"; + forceSSL = true; + listenAddresses = config.me.localAddrs; + + locations."/" = { + proxyPass = "http://[::1]:${toString config.services.immich.port}"; + proxyWebsockets = true; + extraConfig = '' + client_max_body_size 50000M; + proxy_read_timeout 600s; + proxy_send_timeout 600s; + send_timeout 600s; + ''; + }; + }; +} diff --git a/hosts/alyssum/networking.nix b/hosts/alyssum/networking.nix index 281cbb6..c25c21f 100644 --- a/hosts/alyssum/networking.nix +++ b/hosts/alyssum/networking.nix @@ -12,4 +12,5 @@ defaultGateway = "192.168.1.1"; nameservers = [ "8.8.8.8" "8.8.4.4" ]; }; + me.localAddrs = [ "100.67.2.1" ]; } diff --git a/hosts/alyssum/restic.nix b/hosts/alyssum/restic.nix new file mode 100644 index 0000000..eec0979 --- /dev/null +++ b/hosts/alyssum/restic.nix @@ -0,0 +1,31 @@ +{ config, lib, ... }: { + age.secrets.restic_env.file = ../../secrets/restic_env.age; + age.secrets.restic_pass.file = ../../secrets/restic_pass.age; + age.secrets.restic_url.file = ../../secrets/restic_url.age; + + services.restic.backups."flower" = { + initialize = true; + createWrapper = true; + progressFps = 0.016666; + + environmentFile = config.age.secrets.restic_env.path; + passwordFile = config.age.secrets.restic_pass.path; + repositoryFile = config.age.secrets.restic_url.path; + + paths = ["/flower"]; + exclude = ["/flower/.snapshots"] + ++ builtins.filter (x: lib.strings.hasPrefix "/flower" x) (builtins.attrNames config.me.binds); + timerConfig = { + # every 6 hours + OnCalendar = "*-*-* 00,06,12,18:00:00"; + Persistent = true; + }; + pruneOpts = [ + "--keep-last 8" + "--keep-daily 7" + "--keep-weekly 5" + "--keep-monthly 12" + "--keep-yearly 75" + ]; + }; +} diff --git a/hosts/alyssum/snapper.nix b/hosts/alyssum/snapper.nix new file mode 100644 index 0000000..0196fe6 --- /dev/null +++ b/hosts/alyssum/snapper.nix @@ -0,0 +1,19 @@ +{ ... }: { + services.snapper = { + cleanupInterval = "1h"; + persistentTimer = true; + snapshotInterval = "*-*-* *:00,30:00"; + configs.home = { + FSTYPE = "btrfs"; + SUBVOLUME = "/flower"; + TIMELINE_CLEANUP = true; + TIMELINE_CREATE = true; + TIMELINE_MIN_AGE = "86400"; + TIMELINE_LIMIT_HOURLY = "24"; + TIMELINE_LIMIT_DAILY = "7"; + TIMELINE_LIMIT_WEEKLY = "5"; + TIMELINE_LIMIT_MONTHLY = "3"; + TIMELINE_LIMIT_YEARLY = "0"; + }; + }; +} diff --git a/hosts/dandelion/default.nix b/hosts/dandelion/default.nix index f65dfd1..37f2f14 100644 --- a/hosts/dandelion/default.nix +++ b/hosts/dandelion/default.nix @@ -34,6 +34,7 @@ ./filesystem.nix ./kernel.nix + ./immich-proxy.nix ./networking.nix ./nginx.nix diff --git a/hosts/dandelion/immich-proxy.nix b/hosts/dandelion/immich-proxy.nix new file mode 100644 index 0000000..037cb08 --- /dev/null +++ b/hosts/dandelion/immich-proxy.nix @@ -0,0 +1,26 @@ +{ config, ... }: +let + fqdn = "photos.lava.moe"; + shareFqdn = "memo.lava.moe"; +in { + services.immich-public-proxy = { + enable = true; + immichUrl = "https://${fqdn}"; + }; + + services.nginx.virtualHosts."${shareFqdn}" = { + useACMEHost = "lava.moe"; + forceSSL = true; + + locations."/" = { + proxyPass = "http://[::1]:${toString config.services.immich-public-proxy.port}"; + proxyWebsockets = true; + extraConfig = '' + client_max_body_size 50000M; + proxy_read_timeout 600s; + proxy_send_timeout 600s; + send_timeout 600s; + ''; + }; + }; +} diff --git a/modules/options.nix b/modules/options.nix index e861c12..0ec037f 100644 --- a/modules/options.nix +++ b/modules/options.nix @@ -49,5 +49,9 @@ in { type = with lib.types; attrsOf str; default = {}; }; + + localAddrs = lib.mkOption { + type = with lib.types; listOf str; + }; }; } diff --git a/modules/system/tailscale.nix b/modules/system/tailscale.nix index 5e3e044..16205f9 100644 --- a/modules/system/tailscale.nix +++ b/modules/system/tailscale.nix @@ -10,4 +10,7 @@ openFirewall = true; useRoutingFeatures = if config.me.environment == "headless" then "both" else "client"; }; + systemd.services.tailscaled.serviceConfig.LogFilterPatterns = [ + "~magicsock.*does not know about peer.*removing route" + ]; } diff --git a/modules/user/git.nix b/modules/user/git.nix index ca2762e..77f6b72 100644 --- a/modules/user/git.nix +++ b/modules/user/git.nix @@ -11,6 +11,7 @@ core.abbrev = 11; safe.directory = "/home/rin/Projects/flakes"; init.defaultBranch = "master"; + push.autoSetupRemote = true; }; }; } diff --git a/secrets.gcrypt/shared.json b/secrets.gcrypt/shared.json index 21378e7..b4338c2 100644 Binary files a/secrets.gcrypt/shared.json and b/secrets.gcrypt/shared.json differ diff --git a/secrets.nix b/secrets.nix index b1f55e5..d7ac2cc 100644 --- a/secrets.nix +++ b/secrets.nix @@ -12,6 +12,10 @@ in { "secrets/passwd_smbkujira.age".publicKeys = [ alyssum rin ]; "secrets/wpa_conf.age".publicKeys = [ alyssum blossom rin ]; + "secrets/restic_env.age".publicKeys = [ alyssum dandelion rin ]; + "secrets/restic_pass.age".publicKeys = [ alyssum dandelion rin ]; + "secrets/restic_url.age".publicKeys = [ alyssum dandelion rin ]; + "secrets/acme_dns.age".publicKeys = [ alyssum dandelion hazel rin ]; "secrets/navidrome_env.age".publicKeys = [ alyssum dandelion rin ]; "secrets/slskd_env.age".publicKeys = [ anemone dandelion rin ]; diff --git a/secrets/restic_env.age b/secrets/restic_env.age new file mode 100644 index 0000000..1917eef --- /dev/null +++ b/secrets/restic_env.age @@ -0,0 +1,10 @@ +age-encryption.org/v1 +-> ssh-ed25519 kOMSPw CYNG6K56RVMY5KP3vTczaCG9DVL3Ryv7QtqRzrdONh4 +VKH43RjHzP2TcyK8bEO8pZzZZeXqNXEDNq4JCkhMXlQ +-> ssh-ed25519 bRFqeQ AmuEljYrO5qqhaJQONYxQZTlaid2qNt+kktiMRDSKl4 +u+KzYFuEx+UCBfdcpup0fbEp1vGMP24nE3MwvcjhTSc +-> ssh-ed25519 U9FXlg IKN6gdqtD0FDOBk5vXuLD7AYuRtCGsIe5CYMJwyvcG4 +f5lkALvyjz1X94JmnG4u9kZ0S1TgZeBv+uxumFPChzQ +--- 3LBfI6E7NfSK1F42/cQkUzrpry6OWCeW/67YOpZe00k +8ĝg9(<9OT.L_C2XT 1L=3WCoze?4sU.<zIy,bP?(b?7dՃU*-<줯aD֐^,?3 Ebb +vH \ No newline at end of file diff --git a/secrets/restic_pass.age b/secrets/restic_pass.age new file mode 100644 index 0000000..d9a6889 Binary files /dev/null and b/secrets/restic_pass.age differ diff --git a/secrets/restic_url.age b/secrets/restic_url.age new file mode 100644 index 0000000..0d3a2d1 --- /dev/null +++ b/secrets/restic_url.age @@ -0,0 +1,9 @@ +age-encryption.org/v1 +-> ssh-ed25519 kOMSPw l9/BY4rhuzGl/MRKjJ6Hyz2AGpsIZlDojQhSzJ8IxzY +tEGqxZOEWHZvTazrDoC4uTOyuT7fgRKXxumxpjdE89o +-> ssh-ed25519 bRFqeQ XQ1wRRwOP1bIiEX/Dh4tkHB3vF1OdZcLNTtVVM1oWgU +S6qXQsPNY0bGaUz+iLoJ0GBL26FtM4h/sgxqvIwOS3g +-> ssh-ed25519 U9FXlg pmY+R/M38tLi1dq2ll9FDv6uaGv8XlkE99NoAemtlGY +FGZodar5ESxmOZYDZ0F8P1FXNzkEpqT6jyJgzY5wLc0 +--- ig7eZey8XraBclyUEJRv1lJUyiOjqsfGc8Q+jjbAuvQ +eĶ@zYtV4%s29>閇(y8% j|PѨ::-YI)C̹I%yٸ:LCfq_ \ No newline at end of file