A nicer way to mount your /home in LXD

Some time ago I blogged about mounting your /home directory inside a LXD container, and that required some slightly dirty tricks and privileged containers for it to work.

Hopefully my colleagues working on LXD now made it much easier and cleaner to do so, even without requiring privileged containers.

A pony

Let's go through things step by step, and try to provide information about how things work along the way.

Mounting /home read-only

The basic idea is to use LXD's devices handling to mount your host's /home directory to the guest's /home:

lxc init ubuntu-daily:z unmapped
lxc config device add unmapped homedir disk source=$HOME path=/home/ubuntu
lxc start unmapped

If you need it to be read-only, then that is the only step you need to take, since the guest's Ubuntu user (UID 1000 inside the guest) will see your /home files just fine, although they will be owned by a UID and GID of "65534" - nobody. The guest's ubuntu can therefore not write to that directory, but can see files according to normal "other" permissions.

Mounting /home read-write

Allowing LXD to remap your user ID

The first step for that is to allow LXD to remap your user ID. Remember, LXD uses linux namespaces to isolate processes, and by default even root is not allowed to reuse UIDs from the host inside containers.

We want to allow the LXD demon (running as root) to remap our host's user ID inside a container:

# Note: $UID is likely to be 1000 on an Ubuntu system if you're the only user.
echo "root:$UID:1" | sudo tee -a /etc/subuid /etc/subgid

This is a one time step, you'll never need to do this again on your host.

Remapping your user ID inside the container

Once LXD is allowed to remap your UID, we need to actually tell it to do it on a per-container basis:

lxd init ubuntu-daily:z remapped
lxc config set remapped raw.idmap "both $UID 1000"

There is a little bit of magic-looking syntax there, but "both $UID 1000" simply means "map both the UID and the GID, from the host's $UID to the guest's 1000".

We could instead set "uid $UID 1000" and "gid $(id -g) 1000" to be more explicit, but the "both" syntax is convenient.

Mounting /home

As before, we can now mount /home inside our container, and we should hopefully be able to access it read-write from inside the container:

lxc config device add remapped homedir disk source=$HOME path=/home/ubuntu

Let's try it now:

lxc start remapped
# Get a root shell
lxc exec remapped /bin/bash
# Switch to our ubuntu user inside the container
su ubuntu
# create a file in /home/ubuntu inside the container
echo 'Opeth rocks' >> $HOME/message

Let's look at our message form outside the container now:

cat $HOME/message

Putting it all together

Here's a more script-like summary:

container_name=remapped
lxc init ubuntu-daily:z $container_name
lxc config set $container_name raw.idmap "both $UID 1000"
lxc config device add $container_name homedir disk source=$HOME path=/home/ubuntu
lxc start $container_name

Easy!