nixos/immich-kiosk: init module

This commit is contained in:
Tom Vincent 2025-10-22 09:12:07 +01:00
parent b43ed48b82
commit a0f178530d
No known key found for this signature in database
GPG key ID: AB184CDBE6AEACDE
4 changed files with 165 additions and 0 deletions

View file

@ -1628,6 +1628,7 @@
./services/web-apps/icingaweb2/icingaweb2.nix
./services/web-apps/icingaweb2/module-monitoring.nix
./services/web-apps/ifm.nix
./services/web-apps/immich-kiosk.nix
./services/web-apps/immich-public-proxy.nix
./services/web-apps/immich.nix
./services/web-apps/invidious.nix

View file

@ -0,0 +1,132 @@
{
config,
lib,
pkgs,
utils,
...
}:
let
cfg = config.services.immich-kiosk;
format = pkgs.formats.json { };
secretsReplacement = utils.genJqSecretsReplacement {
loadCredential = true;
} cfg.settings "/run/immich-kiosk/config.yaml";
in
{
meta.maintainers = with lib.maintainers; [ tlvince ];
options.services.immich-kiosk = {
enable = lib.mkEnableOption "Immich Kiosk slideshow service";
package = lib.mkPackageOption pkgs "immich-kiosk" { };
openFirewall = lib.mkOption {
type = lib.types.bool;
default = false;
description = ''
Whether to open the firewall for the immich-kiosk port.
'';
};
settings = lib.mkOption {
type = lib.types.submodule {
freeformType = format.type;
options = {
immich_url = lib.mkOption {
type = lib.types.str;
default = config.services.immich.settings.server.externalDomain;
defaultText = lib.literalExpression "config.services.immich.settings.server.externalDomain";
description = ''
URL of the immich instance.
'';
};
kiosk.port = lib.mkOption {
type = lib.types.port;
default = 3000;
description = ''
Port on which immich-kiosk will listen.
'';
};
};
};
default = { };
description = ''
Configuration for immich-kiosk. See
<https://docs.immichkiosk.app/configuration/>
for available options. Secret values can be loaded from files using
`._secret = "/path/to/secret";`.
'';
example = lib.literalExpression ''
{
immich_url = "https://immich.example.com";
immich_api_key._secret = "/run/secrets/immich-kiosk-api-key";
albums = [
"4fa933cf-051f-4621-9ac7-8d06776c261c"
"6466548c-4995-4fb5-ab1f-f63cc9ff3e5f"
];
duration = 30;
layout = "splitview";
disable_ui = true;
}
'';
};
};
config = lib.mkIf cfg.enable {
systemd.services.immich-kiosk = {
description = "Immich Kiosk slideshow service";
after = [ "immich-server.service" ];
wantedBy = [ "multi-user.target" ];
preStart = secretsReplacement.script;
serviceConfig = {
DynamicUser = true;
ExecStart = lib.getExe cfg.package;
Group = "immich-kiosk";
LoadCredential = secretsReplacement.credentials;
Restart = "on-failure";
RestartSec = 10;
RuntimeDirectory = "immich-kiosk";
RuntimeDirectoryMode = "0700";
SyslogIdentifier = "immich-kiosk";
Type = "simple";
User = "immich-kiosk";
WorkingDirectory = "/run/immich-kiosk";
# Hardening
CapabilityBoundingSet = [ "" ];
LockPersonality = true;
NoNewPrivileges = true;
PrivateDevices = true;
PrivateTmp = true;
PrivateUsers = true;
ProtectClock = true;
ProtectControlGroups = true;
ProtectHome = true;
ProtectHostname = true;
ProtectKernelLogs = true;
ProtectKernelModules = true;
ProtectKernelTunables = true;
ProtectProc = "invisible";
RestrictAddressFamilies = [
"AF_INET"
"AF_INET6"
];
RestrictNamespaces = true;
RestrictRealtime = true;
RestrictSUIDSGID = true;
SystemCallArchitectures = "native";
SystemCallFilter = [
"@system-service"
"~@privileged"
"~@resources"
];
UMask = "0077";
};
};
networking.firewall.allowedTCPPorts = lib.mkIf cfg.openFirewall [ cfg.settings.kiosk.port ];
};
}

View file

@ -752,6 +752,7 @@ in
iftop = runTest ./iftop.nix;
image-contents = handleTest ./image-contents.nix { };
immich = runTest ./web-apps/immich.nix;
immich-kiosk = runTest ./web-apps/immich-kiosk.nix;
immich-public-proxy = runTest ./web-apps/immich-public-proxy.nix;
immich-vectorchord-migration = runTest ./web-apps/immich-vectorchord-migration.nix;
immich-vectorchord-reindex = runTest ./web-apps/immich-vectorchord-reindex.nix;

View file

@ -0,0 +1,31 @@
{ ... }:
{
name = "immich-kiosk";
nodes.machine =
{ pkgs, ... }:
{
environment.systemPackages = [ pkgs.jq ];
services.immich-kiosk = {
enable = true;
settings = {
immich_url = "http://localhost:2283";
immich_api_key = {
_secret = pkgs.writeText "immich-kiosk-api-key" "dummy-api-key";
};
kiosk = {
port = 3100;
demo_mode = true;
};
};
};
};
testScript = ''
machine.wait_for_unit("immich-kiosk.service")
machine.wait_for_open_port(3100)
machine.succeed("pgrep -x immich-kiosk")
machine.succeed("jq -r .immich_api_key /run/immich-kiosk/config.yaml | grep dummy-api-key")
'';
}