# self-hosted photo gallery { config, lib, ... }: let cfg = config.my.services.photos; inherit (config.networking) domain; in { options.my.services.photos = { enable = lib.mkEnableOption "Photos gallery"; secretsFile = lib.mkOption { type = lib.types.nullOr lib.types.path; default = null; description = '' pass secrets ''; }; port = lib.mkOption { type = lib.types.port; default = 2283; description = '' Web interface port. ''; }; settings = lib.mkOption { type = lib.types.anything; default = { }; description = '' see . ''; }; path = lib.mkOption { type = lib.types.path; default = null; example = "/data/photos"; description = '' Storage path of your original media files (photos and videos) ''; }; }; config = lib.mkIf cfg.enable { services.immich = { enable = true; # mediaLocation = path; inherit (cfg) secretsFile port ; settings = { ffmpeg.transcode = "disabled"; server.externalDomain = "https://photos.${domain}"; } // cfg.settings; environment = { IMMICH_TELEMETRY_INCLUDE = "all"; IMMICH_API_METRICS_PORT = toString (cfg.port + 1); IMMICH_MICROSERVICES_METRICS_PORT = toString (cfg.port + 2); }; }; services.prometheus = { scrapeConfigs = [ { job_name = "immich"; static_configs = [ { targets = [ "localhost:${toString (cfg.port + 1)}" ]; labels = { instance = config.networking.hostName; service = "api"; }; } { targets = [ "localhost:${toString (cfg.port + 2)}" ]; labels = { instance = config.networking.hostName; service = "server"; }; } ]; } ]; }; my.services.webserver.virtualHosts = [ { subdomain = "photos"; inherit (cfg) port; } ]; webapps.apps.photos = { dashboard = { name = "Photos"; category = "media"; icon = "image"; url = "https://photos.${domain}"; method = "get"; }; }; }; }