From 94eb995ee7074acdac664c35d4a67f1aadcdf21e Mon Sep 17 00:00:00 2001 From: Joakim Repomaa Date: Thu, 13 Feb 2025 01:10:52 +0200 Subject: [PATCH] use native immich module --- hosts/freun.dev/services.nix | 24 ++-- modules/services/immich.nix | 222 ++++------------------------------- 2 files changed, 32 insertions(+), 214 deletions(-) diff --git a/hosts/freun.dev/services.nix b/hosts/freun.dev/services.nix index 6c97ad3..a42b7a2 100644 --- a/hosts/freun.dev/services.nix +++ b/hosts/freun.dev/services.nix @@ -12,28 +12,22 @@ let in { services.postgresql.package = pkgs.postgresql_16; + virtualisation.podman.enable = true; + virtualisation.oci-containers.backend = "podman"; modules.storageBoxMounts = { ${immichDataDir} = { path = "/backup/immich"; user = "u407959"; + uid = config.users.users.${config.services.immich.user}.uid; + gid = config.users.groups.${config.services.immich.user}.gid; }; ${syncthingDataDir} = { path = "/backup/syncthing"; user = "u407959"; - uid = config.users.users.syncthing.uid; - gid = config.users.groups.syncthing.gid; - }; - }; - - modules.services = { - immich = { - enable = true; - subdomain = "img"; - dataDir = immichDataDir; - storageDirs = [ syncthingDataDir ]; - version = "v1.125.7"; + uid = config.users.users.${config.services.syncthing.user}.uid; + gid = config.users.groups.${config.services.syncthing.user}.gid; }; }; @@ -140,5 +134,11 @@ in enable = true; subdomain = "ws"; }; + + immich = { + enable = true; + subdomain = "img"; + mediaLocation = immichDataDir; + }; }; } diff --git a/modules/services/immich.nix b/modules/services/immich.nix index 2090a27..18ac302 100644 --- a/modules/services/immich.nix +++ b/modules/services/immich.nix @@ -1,223 +1,41 @@ -{ pkgs, lib, config, ... }: +{ lib, config, ... }: let - cfg = config.modules.services.immich; - secrets = config.age.secrets; + cfg = config.services.immich; fqdn = "${cfg.subdomain}.${config.networking.domain}"; - - volumeServices = names: ( - lib.lists.foldl - (services: name: - services // { - "podman-volume-immich_${name}" = { - path = [ pkgs.podman ]; - serviceConfig = { - Type = "oneshot"; - RemainAfterExit = true; - }; - script = '' - podman volume inspect immich_${name} || podman volume create immich_${name} - ''; - partOf = [ "podman-compose-immich-root.target" ]; - wantedBy = [ "podman-compose-immich-root.target" ]; - }; - } - ) - { } - names - ); - - containerServices = services: ( - lib.lists.foldl - (acc: { name, volumes ? [ ], ... }: - let - volume_services = map (volume: "podman-volume-immich_${volume}.service") volumes; - dependent_services = [ "podman-network-immich_default.service" ] ++ volume_services; - in - - acc // { - "podman-immich_${name}" = { - serviceConfig = { - Restart = lib.mkOverride 500 "always"; - }; - after = dependent_services; - requires = dependent_services; - partOf = [ - "podman-compose-immich-root.target" - ]; - wantedBy = [ - "podman-compose-immich-root.target" - ]; - }; - } - ) - { } - services - ); - - environment = { - TZ = cfg.timezone; - DB_USERNAME = "postgres"; - POSTGRES_USER = environment.DB_USERNAME; - DB_DATABASE_NAME = "immich"; - }; in { - options.modules.services.immich = { - enable = lib.mkEnableOption "Enable Immich"; + options.services.immich = { subdomain = lib.mkOption { type = lib.types.str; }; timezone = lib.mkOption { type = lib.types.str; - default = "Europe/Helsinki"; + default = "UTC"; }; - version = lib.mkOption { - type = lib.types.str; - default = "latest"; - }; - port = lib.mkOption { + uid = lib.mkOption { type = lib.types.int; - default = 2283; + default = 990; }; - dataDir = lib.mkOption { - type = lib.types.str; - }; - storageDirs = lib.mkOption { - type = lib.types.listOf lib.types.str; - default = [ ]; + gid = lib.mkOption { + type = lib.types.int; + default = 997; }; }; - - config = lib.mkIf cfg.enable - { - virtualisation.podman = { - enable = true; - autoPrune.enable = true; - dockerCompat = true; - defaultNetwork.settings = { - # Required for container networking to be able to use names. - dns_enabled = true; + config = lib.mkIf cfg.enable { + services = { + immich = { + environment = { + TZ = cfg.timezone; }; + settings.server.externalDomain = "https://${fqdn}"; }; - - virtualisation.oci-containers.backend = "podman"; - - networking.firewall.trustedInterfaces = [ "podman1" ]; - modules.firewall.interfaces.podman1 = [ "dns" ]; - - # Containers - virtualisation.oci-containers.containers = { - "immich_machine_learning" = { - image = "ghcr.io/immich-app/immich-machine-learning:${cfg.version}"; - inherit environment; - environmentFiles = [ - secrets.immich.path - ]; - volumes = [ - "immich_model_cache:/cache:rw" - ]; - log-driver = "journald"; - extraOptions = [ - "--network-alias=immich-machine-learning" - "--network=immich_default" - ]; - }; - - "immich_postgres" = { - image = "registry.hub.docker.com/tensorchord/pgvecto-rs:pg14-v0.2.0"; - environmentFiles = [ - secrets.immich.path - ]; - environment = environment // { - POSTGRES_INITDB_ARGS = "--data-checksums"; - }; - volumes = [ - "immich_db_data:/var/lib/postgresql/data:rw" - ]; - cmd = [ "postgres" "-c" "shared_preload_libraries=vectors.so" "-c" "search_path=\"$user\", public, vectors" "-c" "logging_collector=on" "-c" "max_wal_size=2GB" "-c" "shared_buffers=512MB" "-c" "wal_compression=on" ]; - log-driver = "journald"; - extraOptions = [ - "--network-alias=database" - "--network=immich_default" - ]; - }; - - "immich_redis" = { - image = "registry.hub.docker.com/library/redis:6.2-alpine"; - inherit environment; - environmentFiles = [ - secrets.immich.path - ]; - log-driver = "journald"; - extraOptions = [ - "--network-alias=redis" - "--network=immich_default" - ]; - }; - - "immich_server" = { - image = "ghcr.io/immich-app/immich-server:${cfg.version}"; - inherit environment; - environmentFiles = [ - secrets.immich.path - ]; - volumes = [ - "/etc/localtime:/etc/localtime:ro" - "${cfg.dataDir}:/usr/src/app/upload:rw" - ] ++ map (dir: "${dir}:${dir}:ro") cfg.storageDirs; - ports = [ - "${toString cfg.port}:2283/tcp" - ]; - dependsOn = [ - "immich_postgres" - "immich_redis" - ]; - log-driver = "journald"; - extraOptions = [ - "--network-alias=immich-server" - "--network=immich_default" - ]; - }; - }; - - systemd.services = (containerServices [ - { name = "machine_learning"; volumes = [ "model_cache" ]; } - { name = "postgres"; volumes = [ "db_data" ]; } - { name = "redis"; } - { name = "server"; } - ]) // { - # Networks - "podman-network-immich_default" = { - path = [ pkgs.podman ]; - serviceConfig = { - Type = "oneshot"; - RemainAfterExit = true; - ExecStop = "${pkgs.podman}/bin/podman network rm -f immich_default"; - }; - script = '' - podman network inspect immich_default || podman network create immich_default - ''; - partOf = [ "podman-compose-immich-root.target" ]; - wantedBy = [ "podman-compose-immich-root.target" ]; - }; - } // (volumeServices [ - "db_data" - "model_cache" - ]); - - # Root service - # When started, this will automatically create all resources and start - # the containers. When stopped, this will teardown all resources. - systemd.targets."podman-compose-immich-root" = { - unitConfig = { - Description = "Root target generated by compose2nix."; - }; - wantedBy = [ "multi-user.target" ]; - }; - - services.webserver = { + webserver = { enable = lib.mkDefault true; vHosts.${fqdn}.locations."/".proxyPort = cfg.port; }; }; + + users.users.${cfg.user}.uid = cfg.uid; + users.groups.${cfg.user}.gid = cfg.gid; + }; }