Unverified Commit 503c288f authored by Ryan Lahfa's avatar Ryan Lahfa Committed by GitHub
Browse files

Merge pull request #207567 from Stunkymonkey/photoprism-module-init

nixos/photoprism: init module
parents a6d01de4 0214f024
Loading
Loading
Loading
Loading
+8 −0
Original line number Diff line number Diff line
@@ -99,6 +99,14 @@
          <link xlink:href="options.html#opt-services.ulogd.enable">services.ulogd</link>.
        </para>
      </listitem>
      <listitem>
        <para>
          <link xlink:href="https://photoprism.app/">photoprism</link>,
          a AI-Powered Photos App for the Decentralized Web. Available
          as
          <link xlink:href="options.html#opt-services.photoprism.enable">services.photoprism</link>.
        </para>
      </listitem>
    </itemizedlist>
  </section>
  <section xml:id="sec-release-23.05-incompatibilities">
+2 −0
Original line number Diff line number Diff line
@@ -34,6 +34,8 @@ In addition to numerous new and upgraded packages, this release has the followin

- [ulogd](https://www.netfilter.org/projects/ulogd/index.html), a userspace logging daemon for netfilter/iptables related logging. Available as [services.ulogd](options.html#opt-services.ulogd.enable).

- [photoprism](https://photoprism.app/), a AI-Powered Photos App for the Decentralized Web. Available as [services.photoprism](options.html#opt-services.photoprism.enable).

## Backward Incompatibilities {#sec-release-23.05-incompatibilities}

<!-- To avoid merge conflicts, consider adding your item at an arbitrary place in the list instead. -->
+1 −0
Original line number Diff line number Diff line
@@ -1165,6 +1165,7 @@
  ./services/web-apps/peertube.nix
  ./services/web-apps/pgpkeyserver-lite.nix
  ./services/web-apps/phylactery.nix
  ./services/web-apps/photoprism.nix
  ./services/web-apps/pict-rs.nix
  ./services/web-apps/plantuml-server.nix
  ./services/web-apps/plausible.nix
+155 −0
Original line number Diff line number Diff line
{ config, pkgs, lib, ... }:
let
  cfg = config.services.photoprism;

  env = {
    PHOTOPRISM_ORIGINALS_PATH = cfg.originalsPath;
    PHOTOPRISM_STORAGE_PATH = cfg.storagePath;
    PHOTOPRISM_IMPORT_PATH = cfg.importPath;
    PHOTOPRISM_HTTP_HOST = cfg.address;
    PHOTOPRISM_HTTP_PORT = toString cfg.port;
  } // (
    lib.mapAttrs (_: toString) cfg.settings
  );

  manage =
    let
      setupEnv = lib.concatStringsSep "\n" (lib.mapAttrsToList (name: val: "export ${name}=${lib.escapeShellArg val}") env);
    in
    pkgs.writeShellScript "manage" ''
      ${setupEnv}
      exec ${cfg.package}/bin/photoprism "$@"
    '';
in
{
  meta.maintainers = with lib.maintainers; [ stunkymonkey ];

  options.services.photoprism = {

    enable = lib.mkEnableOption (lib.mdDoc "Photoprism web server");

    passwordFile = lib.mkOption {
      type = lib.types.nullOr lib.types.path;
      default = null;
      description = lib.mdDoc ''
        Admin password file.
      '';
    };

    address = lib.mkOption {
      type = lib.types.str;
      default = "localhost";
      description = lib.mdDoc ''
        Web interface address.
      '';
    };

    port = lib.mkOption {
      type = lib.types.port;
      default = 2342;
      description = lib.mdDoc ''
        Web interface port.
      '';
    };

    originalsPath = lib.mkOption {
      type = lib.types.path;
      default = null;
      example = "/data/photos";
      description = lib.mdDoc ''
        Storage path of your original media files (photos and videos).
      '';
    };

    importPath = lib.mkOption {
      type = lib.types.str;
      default = "import";
      description = lib.mdDoc ''
        Relative or absolute to the `originalsPath` from where the files should be imported.
      '';
    };

    storagePath = lib.mkOption {
      type = lib.types.path;
      default = "/var/lib/photoprism";
      description = lib.mdDoc ''
        Location for sidecar, cache, and database files.
      '';
    };

    package = lib.mkPackageOptionMD pkgs "photoprism" { };

    settings = lib.mkOption {
      type = lib.types.attrsOf lib.types.str;
      default = { };
      description = lib.mdDoc ''
        See [the getting-started guide](https://docs.photoprism.app/getting-started/config-options/) for available options.
      '';
      example = {
        PHOTOPRISM_DEFAULT_LOCALE = "de";
        PHOTOPRISM_ADMIN_USER = "root";
      };
    };
  };

  config = lib.mkIf cfg.enable {
    systemd.services.photoprism = {
      description = "Photoprism server";

      serviceConfig = {
        Restart = "on-failure";
        User = "photoprism";
        Group = "photoprism";
        DynamicUser = true;
        StateDirectory = "photoprism";
        WorkingDirectory = "/var/lib/photoprism";
        RuntimeDirectory = "photoprism";

        LoadCredential = lib.optionalString (cfg.passwordFile != null)
          "PHOTOPRISM_ADMIN_PASSWORD:${cfg.passwordFile}";

        CapabilityBoundingSet = "";
        LockPersonality = true;
        PrivateDevices = true;
        PrivateUsers = true;
        ProtectClock = true;
        ProtectControlGroups = true;
        ProtectHome = true;
        ProtectHostname = true;
        ProtectKernelLogs = true;
        ProtectKernelModules = true;
        ProtectKernelTunables = true;
        RestrictAddressFamilies = [ "AF_UNIX" "AF_INET" "AF_INET6" ];
        RestrictNamespaces = true;
        RestrictRealtime = true;
        SystemCallArchitectures = "native";
        SystemCallFilter = [ "@system-service" "~@privileged @setuid @keyring" ];
        UMask = "0066";
      } // lib.optionalAttrs (cfg.port < 1024) {
        AmbientCapabilities = [ "CAP_NET_BIND_SERVICE" ];
        CapabilityBoundingSet = [ "CAP_NET_BIND_SERVICE" ];
      };

      wantedBy = [ "multi-user.target" ];
      environment = env;

      # reminder: easier password configuration will come in https://github.com/photoprism/photoprism/pull/2302
      preStart = ''
        ln -sf ${manage} photoprism-manage

        ${lib.optionalString (cfg.passwordFile != null) ''
          export PHOTOPRISM_ADMIN_PASSWORD=$(cat "$CREDENTIALS_DIRECTORY/PHOTOPRISM_ADMIN_PASSWORD")
        ''}
        exec ${cfg.package}/bin/photoprism migrations run -f
      '';

      script = ''
        ${lib.optionalString (cfg.passwordFile != null) ''
          export PHOTOPRISM_ADMIN_PASSWORD=$(cat "$CREDENTIALS_DIRECTORY/PHOTOPRISM_ADMIN_PASSWORD")
        ''}
        exec ${cfg.package}/bin/photoprism start
      '';
    };
  };
}
+1 −0
Original line number Diff line number Diff line
@@ -513,6 +513,7 @@ in {
  pgjwt = handleTest ./pgjwt.nix {};
  pgmanage = handleTest ./pgmanage.nix {};
  phosh = handleTest ./phosh.nix {};
  photoprism = handleTest ./photoprism.nix {};
  php = handleTest ./php {};
  php80 = handleTest ./php { php = pkgs.php80; };
  php81 = handleTest ./php { php = pkgs.php81; };
Loading