Immich module: External Libraries inside home directory: permission issue

I know this is less of a NixOS question but the upstream only supports users of the “official method” of installation, which is via Docker. I’m using the NixOS service. The configuration is trivial services.immich.enable=true;.

I have two directories, /data and /home/artem/Pictures/archive with the same permissions: 755 (the prefix directories of the latter all also have 755). The former is fine as an “External Library” and the latter raises an error EACCES: permission denied, stat. Any ideas why is the difference and how to fix the latter directory?

Probably because one of the parent directories doesn’t have sufficiently loose perms.
Usually /home/<user> is 700… If it’s 755 as you say, then I wonder if there’s some ACLs?

My /home/<user> is indeed 755

/home🔒 
❯ ll
drwxr-xr-x - artem  8 Jan 10:22 artem
drwx------ - root  15 May  2024 lost+found

thanks to systemd.tmpfiles.rules.

I don’t know how to investigate ACL: I’ve never deal with it. Do you have any ideas by any chance?

Immich probably can’t access /home/artem/Pictures/archive because /home/artem is 700, which is typical for home directories, and directory access requires going through all parent directories.

I would not recommend doing a chmod 755 on your home directory, but it would probably solve your problem, in a “forgot my keys, broke a window” kind of way.

[EDIT: didn’t read your post carefully enough. But the below might work for you anyway if there’s other home folder policy going on, and then you don’t have to 755 your ~.]

Personally, I use bind mounts to have files inside my home directory also accessible to a service user. In your case, you could do something like this:

fileSystems."/media/immich/archive" = {
  device = "/home/artem/Pictures/archive";
  options = [ "bind" "nofail" ];
};

then mkdir -p /media/immich/archive and chmod 755 those instead. (I would chmod 000 the last archive folder there since you’re going to bind mount the other folder over it; this prevents you from accidentally writing files there when the bind mount isn’t mounted.)

If you don’t know what they are, then it’s unlikely you have any set, it was a shot in the dark.
But basically you would check getfacl to verify if there are any. (I think getfacl -e <path> would suffice.)

1 Like

Terrific! It works like a charm. I heard of bind mounts before but wasn’t sure what they’re good for or what are the limitations. I’ll read up about them now.

A little nitpick: for future generations, you could fix the name of the property fileSystems.

1 Like

Oops, I was retyping from my configs because my configs are formatted differently and missed that. I have several ZFS datasets mounted in my home folder and remounted as bind mounts, so I have a helper function

bindMount = dev: { device = dev; options = [ "bind" "nofail" ]; };

and several declarations like

"/pool/me/doc" = bindMount "/home/me/doc";

Glad to hear it works for you.

Beautiful, I’ll reuse this function!