diff --git a/nixos/common/global/secrets/rekeyed/fuchsia/146f3229661998a1ca74449720287a7d-smb-secrets.age b/nixos/common/global/secrets/rekeyed/fuchsia/146f3229661998a1ca74449720287a7d-smb-secrets.age new file mode 100644 index 0000000..0d75c86 --- /dev/null +++ b/nixos/common/global/secrets/rekeyed/fuchsia/146f3229661998a1ca74449720287a7d-smb-secrets.age @@ -0,0 +1,8 @@ +age-encryption.org/v1 +-> ssh-ed25519 jVljVA ILfVChFf5s9U6CODItB/TqS1tUaAEeoLAGiNKPbDclU +MCyVqjOPexZm+is5JWG5zfbS26nJj/Z4mk6SJDufBPM +-> RƥՐII9s~a{'<5|o;_*T'|ysvt(X_J.`r`"|*[ \ No newline at end of file diff --git a/nixos/common/global/secrets/rekeyed/viridian/4108bf86376b696948d4139797cfc8ba-microbin.age b/nixos/common/global/secrets/rekeyed/viridian/4108bf86376b696948d4139797cfc8ba-microbin.age new file mode 100644 index 0000000..e9b6d06 Binary files /dev/null and b/nixos/common/global/secrets/rekeyed/viridian/4108bf86376b696948d4139797cfc8ba-microbin.age differ diff --git a/nixos/common/global/secrets/rekeyed/viridian/baf095ad1a114007e5c55aa2871fe105-borgbackup.age b/nixos/common/global/secrets/rekeyed/viridian/baf095ad1a114007e5c55aa2871fe105-borgbackup.age deleted file mode 100644 index 96cec22..0000000 --- a/nixos/common/global/secrets/rekeyed/viridian/baf095ad1a114007e5c55aa2871fe105-borgbackup.age +++ /dev/null @@ -1,8 +0,0 @@ -age-encryption.org/v1 --> ssh-ed25519 KTkZog 5sg/hpf/62ScHhTff9oK26rKUHOOIOkaEvz6azRbIFs -8YDQXQULAwfzazasdUqr+DhBMm0p4957vywLCmbsPOQ --> ^)fem:-grease ,C tq3PQ#" -Dp5AeElkIQ9RTy0qPV91kur2jWvk2uJTgSRqk1gwoM8vUJM/BbpdqsimUCI0PFxG -Dd507GmCEWDrmovhpAIBS1lAqlY ---- +Xft4rCt53z0qwZsydGBaUanbAxv06yRHgJeDw6yUAI -$KǂK@j]lfNV* jmCm"ށDnTwܟ[ \ No newline at end of file diff --git a/nixos/viridian/configuration.nix b/nixos/viridian/configuration.nix index bb3286c..44a9a41 100644 --- a/nixos/viridian/configuration.nix +++ b/nixos/viridian/configuration.nix @@ -6,25 +6,32 @@ # Our user configuration and optional user units ../common/users/sajenim + # Containers + ./containers/jellyfin + ./containers/jellyseerr + ./containers/lidarr + ./containers/mealie + ./containers/microbin + ./containers/prowlarr + ./containers/qbittorrent + ./containers/radarr + ./containers/recyclarr + ./containers/sonarr + # Services ./services/borgbackup ./services/crowdsec ./services/forgejo + ./services/grafana ./services/immich ./services/lighttpd ./services/minecraft ./services/mpd + ./services/mysql ./services/paperless-ngx + ./services/prometheus ./services/traefik - # Multimedia - ./multimedia/jellyfin - ./multimedia/lidarr - ./multimedia/prowlarr - ./multimedia/qbittorrent - ./multimedia/radarr - ./multimedia/sonarr - # Setup our hardware ./hardware-configuration.nix ]; diff --git a/nixos/viridian/multimedia/jellyfin/default.nix b/nixos/viridian/containers/jellyfin/default.nix similarity index 100% rename from nixos/viridian/multimedia/jellyfin/default.nix rename to nixos/viridian/containers/jellyfin/default.nix diff --git a/nixos/viridian/containers/jellyseerr/default.nix b/nixos/viridian/containers/jellyseerr/default.nix new file mode 100644 index 0000000..47bb4c5 --- /dev/null +++ b/nixos/viridian/containers/jellyseerr/default.nix @@ -0,0 +1,43 @@ +{...}: let + port = "5055"; +in { + virtualisation.oci-containers.containers = { + # Request management + jellyseerr = { + autoStart = true; + image = "ghcr.io/hotio/jellyseerr:release-1.9.2"; + ports = [ + "${port}:5055/tcp" # WebUI + ]; + volumes = [ + "/srv/containers/jellyseerr:/config" + ]; + environment = { + PUID = "1000"; + PGID = "100"; + }; + extraOptions = [ + "--network=media-stack" + ]; + }; + }; + + services.traefik.dynamicConfigOptions.http.routers = { + jellyseerr = { + rule = "Host(`jellyseerr.kanto.dev`)"; + entryPoints = [ + "websecure" + ]; + middlewares = [ + "internal" + ]; + service = "jellyseerr"; + }; + }; + + services.traefik.dynamicConfigOptions.http.services = { + jellyseerr.loadBalancer.servers = [ + {url = "http://127.0.0.1:${port}";} + ]; + }; +} diff --git a/nixos/viridian/multimedia/lidarr/default.nix b/nixos/viridian/containers/lidarr/default.nix similarity index 100% rename from nixos/viridian/multimedia/lidarr/default.nix rename to nixos/viridian/containers/lidarr/default.nix diff --git a/nixos/viridian/containers/mealie/default.nix b/nixos/viridian/containers/mealie/default.nix new file mode 100644 index 0000000..42a6f7c --- /dev/null +++ b/nixos/viridian/containers/mealie/default.nix @@ -0,0 +1,47 @@ +{...}: let + port = "9925"; +in { + virtualisation.oci-containers.containers = { + mealie = { + autoStart = true; + image = "ghcr.io/mealie-recipes/mealie:v1.11.0"; + ports = [ + "${port}:9000" + ]; + volumes = [ + "/srv/containers/mealie:/app/data/" + ]; + environment = { + ALLOW_SIGNUP = "false"; + PUID = "1000"; + PGID = "100"; + TZ = "Australia/Perth"; + MAX_WORKERS = "1"; + WEB_CONCURRENCY = "1"; + BASE_URL = "https://mealie.kanto.dev"; + SECURITY_MAX_LOGIN_ATTEMPTS = "3"; + SECRURITY_USER_LOCKOUT_TIME = "72"; + }; + }; + }; + + services.traefik.dynamicConfigOptions.http.routers = { + mealie = { + rule = "Host(`mealie.kanto.dev`)"; + entryPoints = [ + "websecure" + ]; + middlewares = [ + "crowdsec" + "geoblock" + ]; + service = "mealie"; + }; + }; + + services.traefik.dynamicConfigOptions.http.services = { + mealie.loadBalancer.servers = [ + {url = "http://127.0.0.1:${port}";} + ]; + }; +} diff --git a/nixos/viridian/containers/microbin/default.nix b/nixos/viridian/containers/microbin/default.nix new file mode 100644 index 0000000..248a623 --- /dev/null +++ b/nixos/viridian/containers/microbin/default.nix @@ -0,0 +1,47 @@ +{config, ...}: let + port = "8181"; +in { + age.secrets.microbin = { + # Environment variables for microbin + rekeyFile = ./environment.age; + owner = "sajenim"; + group = "users"; + }; + + virtualisation.oci-containers.containers = { + # Self-hosted, open-source pastbin + microbin = { + autoStart = true; + image = "danielszabo99/microbin:2.0.4"; + ports = [ + "${port}:8080/tcp" # WebUI + ]; + volumes = [ + # Container data + "/srv/containers/microbin:/app/microbin_data:rw" + ]; + environmentFiles = [ + config.age.secrets.microbin.path + ]; + }; + }; + + services.traefik.dynamicConfigOptions.http.routers = { + microbin = { + rule = "Host(`bin.kanto.dev`)"; + entryPoints = [ + "websecure" + ]; + middlewares = [ + "internal" + ]; + service = "microbin"; + }; + }; + + services.traefik.dynamicConfigOptions.http.services = { + microbin.loadBalancer.servers = [ + {url = "http://127.0.0.1:${port}";} + ]; + }; +} diff --git a/nixos/viridian/containers/microbin/environment.age b/nixos/viridian/containers/microbin/environment.age new file mode 100644 index 0000000..160a5cd Binary files /dev/null and b/nixos/viridian/containers/microbin/environment.age differ diff --git a/nixos/viridian/multimedia/prowlarr/default.nix b/nixos/viridian/containers/prowlarr/default.nix similarity index 100% rename from nixos/viridian/multimedia/prowlarr/default.nix rename to nixos/viridian/containers/prowlarr/default.nix diff --git a/nixos/viridian/multimedia/qbittorrent/default.nix b/nixos/viridian/containers/qbittorrent/default.nix similarity index 100% rename from nixos/viridian/multimedia/qbittorrent/default.nix rename to nixos/viridian/containers/qbittorrent/default.nix diff --git a/nixos/viridian/multimedia/radarr/default.nix b/nixos/viridian/containers/radarr/default.nix similarity index 100% rename from nixos/viridian/multimedia/radarr/default.nix rename to nixos/viridian/containers/radarr/default.nix diff --git a/nixos/viridian/containers/recyclarr/default.nix b/nixos/viridian/containers/recyclarr/default.nix new file mode 100644 index 0000000..cd7aa60 --- /dev/null +++ b/nixos/viridian/containers/recyclarr/default.nix @@ -0,0 +1,16 @@ +{...}: { + virtualisation.oci-containers.containers = { + # Automatically synchronize recommended settings from the TRaSH guides to your Sonarr/Radarr instances + recyclarr = { + autoStart = true; + image = "ghcr.io/recyclarr/recyclarr:6.0.2"; + volumes = [ + "/srv/containers/recyclarr:/config" + ]; + extraOptions = [ + "--network=media-stack" + ]; + user = "1000:100"; + }; + }; +} diff --git a/nixos/viridian/multimedia/sonarr/default.nix b/nixos/viridian/containers/sonarr/default.nix similarity index 100% rename from nixos/viridian/multimedia/sonarr/default.nix rename to nixos/viridian/containers/sonarr/default.nix diff --git a/nixos/viridian/hardware-configuration.nix b/nixos/viridian/hardware-configuration.nix index e30e398..8f59566 100644 --- a/nixos/viridian/hardware-configuration.nix +++ b/nixos/viridian/hardware-configuration.nix @@ -3,7 +3,9 @@ lib, pkgs, ... -}: { +}: let + hostname = config.networking.hostName; +in { imports = [ # Our ephemeral system. Wipe root on reboot. ../common/optional/ephemeral-btrfs.nix @@ -69,6 +71,12 @@ options = ["subvol=services" "compress=zstd"]; }; + fileSystems."/srv/backup" = { + device = "/dev/disk/by-label/data"; + fsType = "btrfs"; + options = ["subvol=backup" "compress=zstd"]; + }; + fileSystems."/srv/shares" = { device = "/dev/disk/by-label/data"; fsType = "btrfs"; diff --git a/nixos/viridian/services/borgbackup/default.nix b/nixos/viridian/services/borgbackup/default.nix index 142feae..d2a226f 100644 --- a/nixos/viridian/services/borgbackup/default.nix +++ b/nixos/viridian/services/borgbackup/default.nix @@ -1,33 +1,33 @@ -{config, ...}: { - age.secrets.borgbackup = { - rekeyFile = ./passphrase.age; - }; - - services.borgbackup.jobs."borgbase" = { - paths = [ - # Shares - "/srv/shares/sajenim" - # Services - "/srv/services/forgejo" - "/srv/services/immich" - "/srv/services/minecraft" - "/srv/services/paperless-ngx" - # Containers - "/srv/containers/jellyfin" - "/srv/containers/lidarr" - "/srv/containers/prowlarr" - "/srv/containers/qbittorrent" - "/srv/containers/radarr" - "/srv/containers/sonarr" - ]; - - repo = "o93k24r6@o93k24r6.repo.borgbase.com:repo"; - encryption = { - mode = "repokey-blake2"; - passCommand = "cat ${config.age.secrets.traefik.path}"; +{...}: { + services.borgbackup.jobs = { + containers = { + paths = [ + "/srv/containers" + ]; + encryption.mode = "none"; + repo = "/srv/backup/containers"; + compression = "auto,zstd"; + startAt = "daily"; + }; + + services = { + paths = [ + "/srv/services" + ]; + encryption.mode = "none"; + repo = "/srv/backup/services"; + compression = "auto,zstd"; + startAt = "daily"; + }; + + shares = { + paths = [ + "/srv/shares" + ]; + encryption.mode = "none"; + repo = "/srv/backup/shares"; + compression = "auto,zstd"; + startAt = "daily"; }; - environment.BORG_RSH = "ssh -i /etc/ssh/ssh_host_ed25519_key"; - compression = "auto,lzma"; - startAt = "daily"; }; } diff --git a/nixos/viridian/services/borgbackup/passphrase.age b/nixos/viridian/services/borgbackup/passphrase.age deleted file mode 100644 index 91f3acb..0000000 Binary files a/nixos/viridian/services/borgbackup/passphrase.age and /dev/null differ diff --git a/nixos/viridian/services/grafana/default.nix b/nixos/viridian/services/grafana/default.nix new file mode 100644 index 0000000..e457450 --- /dev/null +++ b/nixos/viridian/services/grafana/default.nix @@ -0,0 +1,56 @@ +{config, ...}: { + # Setup grafana our grafana instance. + services.grafana = { + enable = true; + dataDir = "/srv/services/grafana"; + settings = { + server = { + http_addr = "127.0.0.1"; + http_port = 3400; + domain = "kanto.dev"; + root_url = "https://kanto.dev/grafana/"; + serve_from_sub_path = true; + }; + database = { + type = "mysql"; + name = "grafana"; + user = "grafana"; + host = "/var/run/mysqld/mysqld.sock"; + }; + }; + }; + + # Setup our database for grafana. + services.mysql = { + ensureUsers = [ + { + name = "grafana"; + ensurePermissions = { + "grafana.*" = "ALL PRIVILEGES"; + }; + } + ]; + ensureDatabases = ["grafana"]; + }; + + # Setup our traefik router. + services.traefik.dynamicConfigOptions.http.routers = { + grafana = { + rule = "Host(`kanto.dev`)"; + entryPoints = [ + "websecure" + ]; + middlewares = [ + "internal" + ]; + service = "grafana"; + }; + }; + + # Setup our traefik service. + services.traefik.dynamicConfigOptions.http.services = { + grafana.loadBalancer.servers = [ + {url = "http://127.0.0.1:${toString config.services.grafana.settings.server.http_port}";} + ]; + }; +} diff --git a/nixos/viridian/services/mysql/default.nix b/nixos/viridian/services/mysql/default.nix new file mode 100644 index 0000000..3ca4267 --- /dev/null +++ b/nixos/viridian/services/mysql/default.nix @@ -0,0 +1,7 @@ +{pkgs, ...}: { + services.mysql = { + enable = true; + package = pkgs.mariadb; + dataDir = "/srv/services/mysql"; + }; +} diff --git a/nixos/viridian/services/prometheus/default.nix b/nixos/viridian/services/prometheus/default.nix new file mode 100644 index 0000000..38a67aa --- /dev/null +++ b/nixos/viridian/services/prometheus/default.nix @@ -0,0 +1,32 @@ +{config, ...}: { + services.prometheus = { + enable = true; + port = 9001; # Port to listen on. + + # Valid in all configuration contexts, defaults for other configuration sections. + globalConfig = { + scrape_interval = "15s"; + }; + + # Collect specific metrics, format them, and expose them through HTTP endpoints for prometheus to scrape. + exporters = { + node = { + enable = true; + enabledCollectors = ["systemd" "processes"]; + port = 9100; + }; + }; + + # Specify a set of targets and parameters describing how to scrape them. + scrapeConfigs = [ + { + job_name = "node"; + static_configs = [ + { + targets = ["127.0.0.1:${toString config.services.prometheus.exporters.node.port}"]; + } + ]; + } + ]; + }; +}