#| file: services/immich/default.nix
{
config,
lib,
...
}:
let
cfg = config.mjm.immich;
in
{
options.mjm.immich = {
enable = lib.mkEnableOption "immich";
};
config = lib.mkIf cfg.enable {
<<config>>
};
_class = "nixos";
}Immich is a self-hosted photo management app. Every photo I take with my phone gets uploaded automatically to Immich.
mjm.services.immich = {
<<service-settings>>
};#| id: service-settings
http = {
port = config.services.immich.port;
health.path = "/api/server/ping";
ingress = {
subdomain = "photos";
authMode = "oidc";
oidc = {
name = "Immich";
clientId = "w0lXREOW6t5xMV1LJLeqMALEjBpTTT86B9iH9GivjSB7UFKP0StzL5A2ahTOrvEy";
clientSecret = "$argon2id$v=19$m=65536,t=3,p=4$Qx7s806gOeZU4Ys7kwsYnw$QPtiSJzNROTerIM+JOhfYTw/qEgZ7gu9rACW1xN446o";
tokenEndpointAuthMethod = "client_secret_post";
redirectUris = [
"https://photos.midna.dev/auth/login"
"https://photos.midna.dev/user-settings"
"app.immich:///oauth-callback"
];
};
};
};Immich is exposed externally at https://photos.midna.dev. It has a "ping" endpoint that Consul uses to check its health.
Immich supports OpenID Connect for logging in, which works both in the browser and from the mobile apps.
#| id: service-settings secrets.enable = true; postgresql.enable = true;
Immich uses PostgreSQL for its database and uses Vault to store its OIDC client secret.
services.immich.enable = true;
The Immich service of course needs to be enabled.
services.immich.mediaLocation = "/mnt/immich";
microvm.shares = [
{
proto = "virtiofs";
tag = "icloud-photos";
source = "/mnt/slow/media/photos";
mountPoint = "/mnt/icloud-photos";
}
{
proto = "virtiofs";
tag = "immich";
source = "/mnt/slow/media/immich";
mountPoint = "/mnt/immich";
}
];Immich stores its media on mirrored HDDs from my NAS. The main storage is mounted into the microVM as /mnt/immich. When I still used an iPhone, my photos would be uploaded to iCloud, and then I would run icloudpd to download them to a directory on the NAS. That directory is mounted into the microVM as /mnt/icloud-photos, and in Immich I've configured that directory as an external library location.
services.immich.database.enable = false;
This might look weird, but it just means that Immich's database is not configured automatically on the same machine: it's using the shared PostgreSQL microVM for its host. No other database configuration is needed.
services.immich.settings.server.externalDomain = "https://photos.midna.dev";
Immich needs to know the URL it's hosted at.
services.immich.settings.oauth = {
enabled = true;
buttonText = "Login with Authelia";
clientId = config.mjm.services.immich.http.ingress.oidc.clientId;
clientSecret._secret = "/run/immich-creds.sock";
issuerUrl = "https://auth.midna.dev/";
};
mjm.spire.creds.immich.aliases."immich-server.service/1__run_immich-creds.sock" =
"immich/managed/oidc_client_secret";These settings configure Immich for OpenID Connect through Authelia. The handling for the client secret is jankier than I would like: it relies on knowing that the NixOS module for Immich uses utils.genJqSecretsReplacement with systemd credentials, the fact that the client secret is the first and only secret in the config, and the particular naming for the systemd credentials generated. So that's pretty brittle, but I don't have a better idea for how to do it right now.
services.immich.machine-learning.enable = false;
I'm not especially interested in Immich detecting faces or objects for me, so I disable the machine learning stuff to reduce resources.
text/gemini;lang=en-USThis content has been proxied by September (UNKNO).