diff --git a/modules/immich/env b/modules/immich/env deleted file mode 100644 index 5c8b109..0000000 --- a/modules/immich/env +++ /dev/null @@ -1,5 +0,0 @@ -PUBLIC_LOGIN_PAGE_MESSAGE= - -IMMICH_WEB_URL=http://immich-web:3000 -IMMICH_SERVER_URL=http://immich-server:3001 -IMMICH_MACHINE_LEARNING_URL=http://immich-machine-learning:3003 \ No newline at end of file diff --git a/modules/immich/module.nix b/modules/immich/module.nix deleted file mode 100644 index 230691a..0000000 --- a/modules/immich/module.nix +++ /dev/null @@ -1,584 +0,0 @@ -{ - config, - lib, - pkgs, - ... -}: -let - inherit (lib) - hasAttr - hasPrefix - maintainers - mapAttrs - mkDefault - mkEnableOption - mkIf - mkMerge - mkOption - mkPackageOption - optional - optionalAttrs - optionalString - types - ; - - cfg = config.services.immich; - serverCfg = config.services.immich.server; - backendCfg = serverCfg.backend; - microservicesCfg = serverCfg.microservices; - webCfg = cfg.web; - mlCfg = cfg.machineLearning; - - isServerPostgresUnix = hasPrefix "/" serverCfg.postgres.host; - postgresEnv = - if isServerPostgresUnix then - { - # If passwordFile is given, this will be overwritten in ExecStart - DB_URL = "socket://${serverCfg.postgres.host}?dbname=${serverCfg.postgres.database}"; - } - else - { - DB_HOSTNAME = serverCfg.postgres.host; - DB_PORT = toString serverCfg.postgres.port; - DB_DATABASE_NAME = serverCfg.postgres.database; - DB_USERNAME = serverCfg.postgres.username; - }; - - typesenseEnv = - { - TYPESENSE_ENABLED = toString serverCfg.typesense.enable; - } - // optionalAttrs serverCfg.typesense.enable { - TYPESENSE_HOST = serverCfg.typesense.host; - TYPESENSE_PORT = toString serverCfg.typesense.port; - TYPESENSE_PROTOCOL = serverCfg.typesense.protocol; - }; - - # Don't start a redis instance if the user sets a custom redis connection - enableRedis = - !hasAttr "REDIS_URL" serverCfg.extraConfig && !hasAttr "REDIS_SOCKET" serverCfg.extraConfig; - redisServerCfg = config.services.redis.servers.immich; - redisEnv = optionalAttrs enableRedis { - REDIS_SOCKET = redisServerCfg.unixSocket; - }; - - serverEnv = - postgresEnv - // typesenseEnv - // redisEnv - // { - NODE_ENV = "production"; - - IMMICH_MEDIA_LOCATION = serverCfg.mediaDir; - IMMICH_MACHINE_LEARNING_URL = - if serverCfg.machineLearningUrl != null then serverCfg.machineLearningUrl else "false"; - }; - - serverStartWrapper = program: '' - set -euo pipefail - mkdir -p ${serverCfg.mediaDir} - - ${optionalString (serverCfg.postgres.passwordFile != null) ( - if isServerPostgresUnix then - ''export DB_URL="socket://${serverCfg.postgres.username}:$(cat ${serverCfg.postgres.passwordFile})@${serverCfg.postgres.host}?dbname=${serverCfg.postgres.database}"'' - else - "export DB_PASSWORD=$(cat ${serverCfg.postgres.passwordFile})" - )} - - ${optionalString serverCfg.typesense.enable '' - export TYPESENSE_API_KEY=$(cat ${serverCfg.typesense.apiKeyFile}) - ''} - - exec ${program} - ''; - - commonServiceConfig = { - Restart = "on-failure"; - - # Hardening - CapabilityBoundingSet = ""; - LockPersonality = true; - MemoryDenyWriteExecute = true; - NoNewPrivileges = true; - PrivateUsers = true; - PrivateTmp = true; - PrivateDevices = true; - PrivateMounts = true; - ProtectClock = true; - ProtectControlGroups = true; - ProtectHome = true; - ProtectHostname = true; - ProtectKernelLogs = true; - ProtectKernelModules = true; - ProtectKernelTunables = true; - ProtectProc = "invisible"; - ProcSubset = "pid"; - # Would re-mount paths ignored by temporary root - # TODO ProtectSystem = "strict"; - RemoveIPC = true; - RestrictAddressFamilies = [ - "AF_INET" - "AF_INET6" - "AF_UNIX" - ]; - RestrictNamespaces = true; - RestrictRealtime = true; - RestrictSUIDSGID = true; - SystemCallArchitectures = "native"; - SystemCallFilter = [ - "@system-service" - "~@privileged" - "@pkey" - ]; - UMask = "0077"; - }; - - serverServiceConfig = { - DynamicUser = true; - User = "immich"; - Group = "immich"; - SupplementaryGroups = optional enableRedis redisServerCfg.user; - - StateDirectory = "immich"; - StateDirectoryMode = "0750"; - WorkingDirectory = "/var/lib/immich"; - - MemoryDenyWriteExecute = false; # nodejs requires this. - EnvironmentFile = mkIf (serverCfg.environmentFile != null) serverCfg.environmentFile; - - TemporaryFileSystem = "/:ro"; - BindReadOnlyPaths = [ - "/nix/store" - "-/etc/resolv.conf" - "-/etc/nsswitch.conf" - "-/etc/hosts" - "-/etc/localtime" - "-/run/postgresql" - ] ++ optional enableRedis redisServerCfg.unixSocket; - }; -in -{ - options.services.immich = { - enable = mkEnableOption "immich" // { - description = '' - Enables immich which consists of a backend server, microservices, - machine-learning and web ui. You can disable or reconfigure components - individually using the subsections. - ''; - }; - - package = mkPackageOption pkgs "immich" { }; - - server = { - mediaDir = mkOption { - type = types.str; - default = "/var/lib/immich/media"; - description = "Directory used to store media files."; - }; - - backend = { - enable = mkEnableOption "immich backend server" // { - default = true; - }; - port = mkOption { - type = types.port; - default = 3001; - description = "Port to bind to."; - }; - - openFirewall = mkOption { - default = false; - type = types.bool; - description = "Whether to open the firewall for the specified port."; - }; - - extraConfig = mkOption { - type = types.attrs; - default = { }; - example = { - LOG_LEVEL = "debug"; - }; - description = '' - Extra configuration options (environment variables). - Refer to [the documented variables](https://documentation.immich.app/docs/install/environment-variables) tagged with 'server' for available options. - ''; - }; - - environmentFile = mkOption { - type = types.nullOr types.path; - default = null; - description = '' - Environment file as defined in systemd.exec(5). May be used to provide - additional secret variables to the service without adding them to the - world-readable Nix store. - ''; - }; - }; - - microservices = { - enable = mkEnableOption "immich microservices" // { - default = true; - }; - - port = mkOption { - type = types.port; - default = 3002; - description = "Port to bind to."; - }; - - openFirewall = mkOption { - default = false; - type = types.bool; - description = "Whether to open the firewall for the specified port."; - }; - - extraConfig = mkOption { - type = types.attrs; - default = { }; - example = { - REVERSE_GEOCODING_PRECISION = 1; - }; - description = '' - Extra configuration options (environment variables). - Refer to [the documented variables](https://documentation.immich.app/docs/install/environment-variables) tagged with 'microservices' for available options. - ''; - }; - - environmentFile = mkOption { - type = types.nullOr types.path; - default = null; - description = '' - Environment file as defined in systemd.exec(5). May be used to provide - additional secret variables to the service without adding them to the - world-readable Nix store. - ''; - }; - }; - - typesense = { - enable = mkEnableOption "typesense" // { - default = true; - }; - - host = mkOption { - type = types.str; - default = "127.0.0.1"; - example = "typesense.example.com"; - description = "Hostname/address of the typesense server to use."; - }; - - port = mkOption { - type = types.port; - default = 8108; - description = "The port of the typesense server to use."; - }; - - protocol = mkOption { - type = types.str; - default = "http"; - description = "The protocol to use when connecting to the typesense server."; - }; - - apiKeyFile = mkOption { - type = types.path; - description = "Sets the api key for authentication with typesense."; - }; - }; - - postgres = { - host = mkOption { - type = types.str; - default = "/run/postgresql"; - description = "Hostname/address of the postgres server to use. If an absolute path is given here, it will be interpreted as a unix socket path."; - }; - - port = mkOption { - type = types.port; - default = 5432; - description = "The port of the postgres server to use."; - }; - - username = mkOption { - type = types.str; - default = "immich"; - description = "The postgres username to use."; - }; - - passwordFile = mkOption { - type = types.nullOr types.path; - default = null; - description = '' - Sets the password for authentication with postgres. - May be unset when using socket authentication. - ''; - }; - - database = mkOption { - type = types.str; - default = "immich"; - description = "The postgres database to use."; - }; - }; - - useMachineLearning = mkOption { - description = "Use the given machine learning server endpoint to enable ML functionality in immich."; - default = true; - type = types.bool; - }; - - machineLearningUrl = mkOption { - type = types.str; - default = "http://127.0.0.1:3003"; - example = "https://immich-ml.internal.example.com"; - description = "The machine learning server endpoint to use."; - }; - - extraConfig = mkOption { - type = types.attrs; - default = { }; - example = { - REDIS_SOCKET = "/run/custom-redis"; - }; - description = '' - Extra configuration options (environment variables) for both backend and microservices. - Refer to [the documented variables](https://documentation.immich.app/docs/install/environment-variables) tagged with both 'server' and 'microservices' for available options. - ''; - }; - - environmentFile = mkOption { - type = types.nullOr types.path; - default = null; - description = '' - Environment file as defined in systemd.exec(5). May be used to provide - additional secret variables to the backend and microservices servers without - adding them to the world-readable Nix store. - ''; - }; - }; - - web = { - enable = mkEnableOption "immich web frontend" // { - default = true; - }; - - port = mkOption { - type = types.port; - default = 3000; - description = "Port to bind to."; - }; - - openFirewall = mkOption { - default = false; - type = types.bool; - description = "Whether to open the firewall for the specified port."; - }; - - serverUrl = mkOption { - type = types.str; - default = "http://127.0.0.1:3001"; - example = "https://immich-backend.internal.example.com"; - description = "The backend server url to use."; - }; - - apiUrlExternal = mkOption { - type = types.str; - default = "/web"; - description = "The api url to use for external requests."; - }; - - extraConfig = mkOption { - type = types.attrs; - default = { }; - example = { - PUBLIC_LOGIN_PAGE_MESSAGE = "My awesome Immich instance!"; - }; - description = '' - Extra configuration options (environment variables). - Refer to [the documented variables](https://documentation.immich.app/docs/install/environment-variables) tagged with 'web' for available options. - ''; - }; - }; - - machineLearning = { - enable = mkEnableOption "immich machine-learning server" // { - default = true; - }; - - port = mkOption { - type = types.port; - default = 3003; - description = "Port to bind to."; - }; - - openFirewall = mkOption { - default = false; - type = types.bool; - description = "Whether to open the firewall for the specified port."; - }; - - extraConfig = mkOption { - type = types.attrs; - default = { }; - example = { - MACHINE_LEARNING_MODEL_TTL = 600; - }; - description = '' - Extra configuration options (environment variables). - Refer to [the documented variables](https://documentation.immich.app/docs/install/environment-variables) tagged with 'machine learning' for available options. - ''; - }; - }; - }; - - config = mkIf cfg.enable { - assertions = [ - { - assertion = !isServerPostgresUnix -> serverCfg.postgres.passwordFile != null; - message = "A database password must be provided when unix sockets are not used."; - } - ]; - - networking.firewall.allowedTCPPorts = mkMerge [ - (mkIf (backendCfg.enable && backendCfg.openFirewall) [ backendCfg.port ]) - (mkIf (microservicesCfg.enable && microservicesCfg.openFirewall) [ microservicesCfg.port ]) - (mkIf (webCfg.enable && webCfg.openFirewall) [ webCfg.port ]) - (mkIf (mlCfg.enable && mlCfg.openFirewall) [ mlCfg.port ]) - ]; - - services.redis.servers.immich.enable = mkIf enableRedis true; - services.redis.vmOverCommit = mkIf enableRedis (mkDefault true); - - systemd.services.immich-server = mkIf backendCfg.enable { - description = "Immich backend server (Self-hosted photo and video backup solution)"; - after = [ - "network.target" - "typesense.service" - "postgresql.service" - "immich-machine-learning.service" - ] ++ optional enableRedis "redis-immich.service"; - wantedBy = [ "multi-user.target" ]; - - environment = - serverEnv - // { - SERVER_PORT = toString backendCfg.port; - } - // mapAttrs (_: toString) serverCfg.extraConfig - // mapAttrs (_: toString) backendCfg.extraConfig; - - script = serverStartWrapper "${cfg.package}/bin/server"; - serviceConfig = mkMerge [ - (commonServiceConfig // serverServiceConfig) - { - EnvironmentFile = mkIf (backendCfg.environmentFile != null) backendCfg.environmentFile; - } - ]; - }; - - systemd.services.immich-microservices = mkIf microservicesCfg.enable { - description = "Immich microservices (Self-hosted photo and video backup solution)"; - after = [ - "network.target" - "typesense.service" - "postgresql.service" - "immich-machine-learning.service" - ] ++ optional enableRedis "redis-immich.service"; - wantedBy = [ "multi-user.target" ]; - - environment = - serverEnv - // { - MICROSERVICES_PORT = toString microservicesCfg.port; - } - // mapAttrs (_: toString) serverCfg.extraConfig - // mapAttrs (_: toString) microservicesCfg.extraConfig; - - script = serverStartWrapper "${cfg.package}/bin/microservices"; - serviceConfig = mkMerge [ - (commonServiceConfig // serverServiceConfig) - { - EnvironmentFile = mkIf (microservicesCfg.environmentFile != null) microservicesCfg.environmentFile; - } - ]; - }; - - systemd.services.immich-web = mkIf webCfg.enable { - description = "Immich web (Self-hosted photo and video backup solution)"; - after = [ - "network.target" - "immich-server.service" - ]; - wantedBy = [ "multi-user.target" ]; - - environment = { - NODE_ENV = "production"; - PORT = toString webCfg.port; - IMMICH_SERVER_URL = webCfg.serverUrl; - IMMICH_API_URL_EXTERNAL = webCfg.apiUrlExternal; - } // mapAttrs (_: toString) webCfg.extraConfig; - - script = '' - set -euo pipefail - export PUBLIC_IMMICH_SERVER_URL=$IMMICH_SERVER_URL - export PUBLIC_IMMICH_API_URL_EXTERNAL=$IMMICH_API_URL_EXTERNAL - exec ${cfg.package.web}/bin/web - ''; - serviceConfig = commonServiceConfig // { - DynamicUser = true; - User = "immich-web"; - Group = "immich-web"; - - MemoryDenyWriteExecute = false; # nodejs requires this. - - TemporaryFileSystem = "/:ro"; - BindReadOnlyPaths = [ - "/nix/store" - "-/etc/resolv.conf" - "-/etc/nsswitch.conf" - "-/etc/hosts" - "-/etc/localtime" - ]; - }; - }; - - systemd.services.immich-machine-learning = mkIf mlCfg.enable { - description = "Immich machine learning (Self-hosted photo and video backup solution)"; - after = [ "network.target" ]; - wantedBy = [ "multi-user.target" ]; - - environment = { - NODE_ENV = "production"; - MACHINE_LEARNING_PORT = toString mlCfg.port; - - MACHINE_LEARNING_CACHE_FOLDER = "/var/cache/immich-ml"; - TRANSFORMERS_CACHE = "/var/cache/immich-ml"; - } // mapAttrs (_: toString) mlCfg.extraConfig; - - serviceConfig = commonServiceConfig // { - ExecStart = "${cfg.package.machine-learning}/bin/machine-learning"; - DynamicUser = true; - User = "immich-ml"; - Group = "immich-ml"; - - MemoryDenyWriteExecute = false; # onnxruntime_pybind11 requires this. - ProcSubset = "all"; # Needs /proc/cpuinfo - - CacheDirectory = "immich-ml"; - CacheDirectoryMode = "0700"; - - # TODO gpu access - - TemporaryFileSystem = "/:ro"; - BindReadOnlyPaths = [ - "/nix/store" - "-/etc/resolv.conf" - "-/etc/nsswitch.conf" - "-/etc/hosts" - "-/etc/localtime" - ]; - }; - }; - - meta.maintainers = with maintainers; [ oddlama ]; - }; -} diff --git a/modules/mount-rock5b/default.nix b/modules/mount-sisko/default.nix similarity index 100% rename from modules/mount-rock5b/default.nix rename to modules/mount-sisko/default.nix diff --git a/modules/rock5b-proxy/default.nix b/modules/sisko-proxy/default.nix similarity index 92% rename from modules/rock5b-proxy/default.nix rename to modules/sisko-proxy/default.nix index 3a324ef..c6c1a7b 100644 --- a/modules/rock5b-proxy/default.nix +++ b/modules/sisko-proxy/default.nix @@ -47,13 +47,16 @@ proxyWebsockets = true; }; }; - - # "jellyfin.aciceri.dev" = { + "paper.aciceri.dev" = { + forceSSL = true; + enableACME = true; + locations."/" = { + proxyPass = "http://localhost:${builtins.toString config.services.paperless.port}"; + }; + }; + # "${config.services.nextcloud.hostName}" = { # forceSSL = true; # enableACME = true; - # locations."/" = { - # proxyPass = "http://localhost:8096"; - # }; # }; # "sevenofnix.aciceri.dev" = { # forceSSL = true; diff --git a/modules/rock5b-samba/default.nix b/modules/sisko-samba/default.nix similarity index 100% rename from modules/rock5b-samba/default.nix rename to modules/sisko-samba/default.nix