From 35497a39310d7be2dd39c53fe90bebf396396de9 Mon Sep 17 00:00:00 2001 From: Oliver Davies Date: Thu, 1 May 2025 00:00:05 +0100 Subject: [PATCH] Automated dev commit --- hosts/nixedo/homelab.nix | 1 + hosts/nixedo/modules/acme.nix | 1 + hosts/nixedo/modules/containers/default.nix | 3 +- .../modules/containers/tubearchivist.nix | 313 ++++++++++++++++++ hosts/nixedo/secrets.nix | 1 + hosts/nixedo/services/containers/default.nix | 5 + hosts/t480/configuration.nix | 2 +- secrets.nix | 5 + secrets/tubearchivist-env.age | 20 ++ 9 files changed, 349 insertions(+), 2 deletions(-) create mode 100644 hosts/nixedo/modules/containers/tubearchivist.nix create mode 100644 hosts/nixedo/services/containers/default.nix create mode 100644 secrets/tubearchivist-env.age diff --git a/hosts/nixedo/homelab.nix b/hosts/nixedo/homelab.nix index fd95d34e..a81a3fc0 100644 --- a/hosts/nixedo/homelab.nix +++ b/hosts/nixedo/homelab.nix @@ -22,6 +22,7 @@ immich.enable = true; jellyfin.enable = true; paperless.enable = true; + tubearchivist.enable = true; uptime-kuma.enable = true; vaultwarden = { diff --git a/hosts/nixedo/modules/acme.nix b/hosts/nixedo/modules/acme.nix index 1eab7abe..3e4e863f 100644 --- a/hosts/nixedo/modules/acme.nix +++ b/hosts/nixedo/modules/acme.nix @@ -39,6 +39,7 @@ "tailwindcss-demo" "talking-drupal-tailwindcss" "tome" + "tubearchivist" "uptime" "vaultwarden" "wp-tailwind" diff --git a/hosts/nixedo/modules/containers/default.nix b/hosts/nixedo/modules/containers/default.nix index 5132a01b..346ef242 100644 --- a/hosts/nixedo/modules/containers/default.nix +++ b/hosts/nixedo/modules/containers/default.nix @@ -1,5 +1,6 @@ { imports = [ - ./pi-hole.nix + # ./pi-hole.nix + ./tubearchivist.nix ]; } diff --git a/hosts/nixedo/modules/containers/tubearchivist.nix b/hosts/nixedo/modules/containers/tubearchivist.nix new file mode 100644 index 00000000..15c50067 --- /dev/null +++ b/hosts/nixedo/modules/containers/tubearchivist.nix @@ -0,0 +1,313 @@ +{ + config, + lib, + pkgs, + ... +}: + +with lib; + +let + cfg = homelab.services.${service}; + service = "tubearchivist"; + homelab = config.features.homelab; +in +{ + options.features.homelab.services.${service} = { + enable = mkEnableOption "Enable ${service}"; + + port = mkOption { + default = 8099; + type = types.port; + }; + + url = mkOption { + default = "${service}.${homelab.baseDomain}"; + type = types.str; + }; + }; + + config = mkIf cfg.enable { + virtualisation = { + oci-containers.backend = "podman"; + podman.enable = true; + }; + + virtualisation.oci-containers.containers."archivist-es" = { + image = "bbilly1/tubearchivist-es"; + + environment = { + "ES_JAVA_OPTS" = "-Xms1g -Xmx1g"; + "discovery.type" = "single-node"; + "path.repo" = "/usr/share/elasticsearch/data/snapshot"; + "xpack.security.enabled" = "true"; + "cluster.routing.allocation.disk.watermark.flood_stage" = "98%"; + "cluster.routing.allocation.disk.watermark.high" = "97%"; + "cluster.routing.allocation.disk.watermark.low" = "95%"; + }; + + environmentFiles = [ + config.age.secrets.tubearchivist-env.path + ]; + + volumes = [ + "tubearchivist_es:/usr/share/elasticsearch/data:rw" + ]; + + log-driver = "journald"; + + extraOptions = [ + "--network-alias=archivist-es" + "--network=tubearchivist_default" + ]; + }; + + systemd.services."podman-archivist-es" = { + serviceConfig = { + Restart = mkOverride 90 "always"; + RestartMaxDelaySec = mkOverride 90 "1m"; + RestartSec = mkOverride 90 "100ms"; + RestartSteps = mkOverride 90 9; + }; + + after = [ + "podman-network-tubearchivist_default.service" + "podman-volume-tubearchivist_es.service" + ]; + + requires = [ + "podman-network-tubearchivist_default.service" + "podman-volume-tubearchivist_es.service" + ]; + + partOf = [ + "podman-compose-tubearchivist-root.target" + ]; + + wantedBy = [ + "podman-compose-tubearchivist-root.target" + ]; + }; + + virtualisation.oci-containers.containers."archivist-redis" = { + image = "redis"; + + volumes = [ + "tubearchivist_redis:/data:rw" + ]; + + dependsOn = [ + "archivist-es" + ]; + + log-driver = "journald"; + + extraOptions = [ + "--network-alias=archivist-redis" + "--network=tubearchivist_default" + ]; + }; + + systemd.services."podman-archivist-redis" = { + serviceConfig = { + Restart = mkOverride 90 "always"; + RestartMaxDelaySec = mkOverride 90 "1m"; + RestartSec = mkOverride 90 "100ms"; + RestartSteps = mkOverride 90 9; + }; + + after = [ + "podman-network-tubearchivist_default.service" + "podman-volume-tubearchivist_redis.service" + ]; + + requires = [ + "podman-network-tubearchivist_default.service" + "podman-volume-tubearchivist_redis.service" + ]; + + partOf = [ + "podman-compose-tubearchivist-root.target" + ]; + + wantedBy = [ + "podman-compose-tubearchivist-root.target" + ]; + }; + + virtualisation.oci-containers.containers."tubearchivist" = { + image = "bbilly1/tubearchivist"; + + environment = { + "ES_URL" = "http://archivist-es:9200"; + "HOST_GID" = "1000"; + "HOST_UID" = "1000"; + "REDIS_CON" = "redis://archivist-redis:6379"; + "TA_HOST" = "http://${cfg.url}"; + "TZ" = "Europe/London"; + }; + + environmentFiles = [ + config.age.secrets.tubearchivist-env.path + ]; + + volumes = [ + "/mnt/media/${service}/cache:/cache:rw" + "/mnt/media/${service}/media:/youtube:rw" + ]; + + ports = [ + "${toString cfg.port}:8000/tcp" + ]; + + dependsOn = [ + "archivist-es" + "archivist-redis" + ]; + + log-driver = "journald"; + + extraOptions = [ + "--health-cmd=[\"curl\", \"-f\", \"http://localhost:8000/health\"]" + "--health-interval=2m0s" + "--health-retries=3" + "--health-start-period=30s" + "--health-timeout=10s" + "--network-alias=tubearchivist" + "--network=tubearchivist_default" + ]; + }; + + systemd.services."podman-tubearchivist" = { + serviceConfig = { + Restart = mkOverride 90 "always"; + RestartMaxDelaySec = mkOverride 90 "1m"; + RestartSec = mkOverride 90 "100ms"; + RestartSteps = mkOverride 90 9; + }; + + after = [ + "podman-network-tubearchivist_default.service" + "podman-volume-tubearchivist_cache.service" + "podman-volume-tubearchivist_media.service" + ]; + + requires = [ + "podman-network-tubearchivist_default.service" + "podman-volume-tubearchivist_cache.service" + "podman-volume-tubearchivist_media.service" + ]; + + partOf = [ + "podman-compose-tubearchivist-root.target" + ]; + + wantedBy = [ + "podman-compose-tubearchivist-root.target" + ]; + }; + + systemd.services."podman-network-tubearchivist_default" = { + path = [ pkgs.podman ]; + + serviceConfig = { + Type = "oneshot"; + RemainAfterExit = true; + ExecStop = "podman network rm -f tubearchivist_default"; + }; + + script = '' + podman network inspect tubearchivist_default || podman network create tubearchivist_default + ''; + + partOf = [ "podman-compose-tubearchivist-root.target" ]; + wantedBy = [ "podman-compose-tubearchivist-root.target" ]; + }; + + systemd.services."podman-volume-tubearchivist_cache" = { + path = [ pkgs.podman ]; + + serviceConfig = { + Type = "oneshot"; + RemainAfterExit = true; + }; + + script = '' + podman volume inspect tubearchivist_cache || podman volume create tubearchivist_cache + ''; + + partOf = [ "podman-compose-tubearchivist-root.target" ]; + wantedBy = [ "podman-compose-tubearchivist-root.target" ]; + }; + + systemd.services."podman-volume-tubearchivist_es" = { + path = [ pkgs.podman ]; + + serviceConfig = { + Type = "oneshot"; + RemainAfterExit = true; + }; + + script = '' + podman volume inspect tubearchivist_es || podman volume create tubearchivist_es + ''; + + partOf = [ "podman-compose-tubearchivist-root.target" ]; + wantedBy = [ "podman-compose-tubearchivist-root.target" ]; + }; + + systemd.services."podman-volume-tubearchivist_media" = { + path = [ pkgs.podman ]; + + serviceConfig = { + Type = "oneshot"; + RemainAfterExit = true; + }; + + script = '' + podman volume inspect tubearchivist_media || podman volume create tubearchivist_media + ''; + + partOf = [ "podman-compose-tubearchivist-root.target" ]; + wantedBy = [ "podman-compose-tubearchivist-root.target" ]; + }; + + systemd.services."podman-volume-tubearchivist_redis" = { + path = [ pkgs.podman ]; + + serviceConfig = { + Type = "oneshot"; + RemainAfterExit = true; + }; + + script = '' + podman volume inspect tubearchivist_redis || podman volume create tubearchivist_redis + ''; + + partOf = [ "podman-compose-tubearchivist-root.target" ]; + wantedBy = [ "podman-compose-tubearchivist-root.target" ]; + }; + + systemd.targets."podman-compose-tubearchivist-root" = { + unitConfig = { + Description = "Root target generated by compose2nix."; + }; + + wantedBy = [ "multi-user.target" ]; + }; + + services.nginx.virtualHosts."${cfg.url}" = { + forceSSL = true; + useACMEHost = homelab.baseDomain; + + locations."/" = { + proxyPass = "http://localhost:${toString cfg.port}"; + recommendedProxySettings = true; + + extraConfig = '' + proxy_buffering off; + ''; + }; + }; + }; +} diff --git a/hosts/nixedo/secrets.nix b/hosts/nixedo/secrets.nix index 6c55583f..c3fa36d6 100644 --- a/hosts/nixedo/secrets.nix +++ b/hosts/nixedo/secrets.nix @@ -2,5 +2,6 @@ age.secrets = { cloudflare.file = ../../secrets/cloudflare.age; cloudflared.file = ../../secrets/cloudflared-credentials.age; + tubearchivist-env.file = ../../secrets/tubearchivist-env.age; }; } diff --git a/hosts/nixedo/services/containers/default.nix b/hosts/nixedo/services/containers/default.nix new file mode 100644 index 00000000..10dea067 --- /dev/null +++ b/hosts/nixedo/services/containers/default.nix @@ -0,0 +1,5 @@ +{ + imports = [ + ./tubearchivist.nix + ]; +} diff --git a/hosts/t480/configuration.nix b/hosts/t480/configuration.nix index a30160af..4e4a2dc9 100644 --- a/hosts/t480/configuration.nix +++ b/hosts/t480/configuration.nix @@ -66,7 +66,6 @@ }; environment.systemPackages = with pkgs; [ - tailscale abook acpi arandr @@ -98,6 +97,7 @@ shotwell slack sxiv + tailscale ttyper upload-to-files xcape diff --git a/secrets.nix b/secrets.nix index ca26e99a..59104be0 100644 --- a/secrets.nix +++ b/secrets.nix @@ -19,4 +19,9 @@ in "secrets/cloudflared-credentials.age".publicKeys = [ hosts.nixedo ] ++ [ users.opdavies ]; + + "secrets/tubearchivist-env.age".publicKeys = [ + hosts.nixedo + hosts.t480 + ] ++ [ users.opdavies ]; } diff --git a/secrets/tubearchivist-env.age b/secrets/tubearchivist-env.age new file mode 100644 index 00000000..8e8fd5c1 --- /dev/null +++ b/secrets/tubearchivist-env.age @@ -0,0 +1,20 @@ +age-encryption.org/v1 +-> ssh-ed25519 IsVD3g JcpSuBgBp3nnPscb55121KL2XeCkBnwRwr57rFYE+nE +o0nLbL0tQWZIwOECYb+/zQsGo9/uoEpuaPqdxoZqY/Y +-> ssh-ed25519 IsVD3g fYyG89/0d3WO+aG9SaZ5+QMGrayd0y6EdnpjEx7mOTM +nbP/TlK5goWZe6ObIvqaRYTa7XPKprVoOeOZBPARON4 +-> ssh-rsa +vTWQw +mrS2MJwu/XgQd0y+bE9pa4iCZk8m1l6WQrnLb7tOaPXiVBObh03k6y9uWsfVSgmh +gnXHBQIAGXtdJ6qabt5jLDQrDxMZw1jxAr5QONR8Y+zmcw3BTvKYmVQRfsRlOM0O +qC4VG7CXcq7tcOEHKi3VliyUZW3R1SzXVhr72VXsug2IbWsNp/plusiA8MmLR3Mf +0N6z8ye1ZKRFHs4Q9ShyLad5JcJtkjrNmhbhQdZlNUQfOf+jrTEFrgKII96pCWqI +2eqpUbA1ameSUXgRknaZjIYQBmJd5ejvClGV5cojlD+DdX0W85mRW/Xj1CinUsGk +QZ+RFQ9GWGLLV8Uba707nbS1yMlnc2afJyG8dWGaH9m2E/9NnsFxCIbcQTrK28Yu +yabdui1sXG8stVWGK4FqCTuxNLv/bWC37IcFQQai9wgZhziyO07QR1jQ2xiMXLBZ +cw3KT8y8yYROzhZCuKoW/FAIrlsQv3ePBv+YEpnLF++2Pa25d1jmJXryAooDpBLd +5gi/hKvBeDPwtgStS0BjPYRM37tQ0UlHkcCqq8v2xeTX7VZpqWrzUcGX4DXCgxxX +Qrj5eDdomUfFH5NE8LWWNfpAlP1SOkM3ebCoa9e1sfEdJUzubIbSuRL/VFTm0SJe +WaUbIuTPOo7Sda6ZgM7lPFylqJNC8bHI5Ch6AH7UWX0 +--- GcN2m5Td0aMEWTrH6ZOyjplhvkHsHrCJfoyyfsbJHZo +xL}va1(t1$Cn߇;ftO@]ycvd +VQ XS;.Oס?HɊJD|'!w9gvRuNSú9 \ No newline at end of file