Best practice for attaching external folder or filesystem?

So far I’ve only built web app containers that are completely self-contained. My next task is to create an email server container which needs transparent access to /srv/imap (very large folder) on the host machine. Is there a best practice for doing this? Or is this a bad idea, and I should think about moving these files in to the container proper?

If using LXD, this can be done reasonably easily, even easier if you don’t need write access in the container.

You’d typically just do:

lxc config device add container-name data disk source=/srv/imap path=/srv/imap

If you need write access and the container is unprivileged, you’ll either need to change the ownership of those files on the host, or use POSIX ACls (setfacl) to allow both the container and host to read and write them.

Thank you, that is exactly what I was looking for. The imap user (in this case, cyrus) will need write access to the external imap folder. But since cyrus is a user in the container, I’m not quite sure how the permissions are handled. With NFS mounts, you can either use the same uid’s on the client and server or use idmapd to create a mapping between uid’s. With SMB mounts, you have to specify a specific user/password when the mount is initiated.

And presumably LXD containers and the host system can share an LDAP database and both use this for authentication; however I’m not entire sure this necessarily works with the command you provide above; it probably depends on precisely how it works. I’m guessing this is a case of RTFM, though? I’m OK with using privileged containers; this is a pretty locked down system.

I use profiles to do this, instead of issuing random device add commands. I find profiles easier to manage and track. I typically use two profiles: One to map the external folder, and one to map the user id (for the containers that need write access). Then I attach the profiles to the containers that need them.

Here’s a profile that shares a folder from the host to a container:

config: {}
description: ""
devices:
  opt:
    path: /var/share/opt
    source: /z/var/opt
    type: disk
name: opt
used_by: []

And here’s a profile that maps uid 2401 between the container and the host:

config:
  raw.idmap: both 2401 2401
description: UID Mapping LXD profile
devices: {}
name: mapping
used_by: []

If an unprivileged container has the opt profile but not the mapping profile, it will have a /var/share/opt folder with read-only access (all files will be owned by user “nobody”).

If the container has both the opt and the mapping profiles, then any files owned by uid 2401 on the host will show up as owned by uid 2401 in the container, therefore if the container has a user with uid 2401, that user (or the container root) can modify those files.

Of course, you can combine both profiles into one, if you don’t need to use them separately. I usually share a folder read-write with one container that maintains the data, and read-only to multiple containers.

1 Like