Mount your /home in LXD
UPDATE: There is now a nicer way to mount /home in your LXD containers , please read my updated article instead.
I've used LXC to host my development environment for a long time, and since the amazing LXD is the new kid on the block I decided to go ahead and see if I could equally easily use it for my day to day usage.
Good news! I can! One feature is slightly less obvious with LXD than it was with LXC however, so after picking my colleague's brains on this, I decided to go ahead and write this blog post.
One very convenient feature of LXC is the "-b" option to the container creation command line, which allows the container to mount the host user's home inside the container. This allows, for example, several containers to work from the same files in different environments, saving disk space but allowing for testing different operating system versions or set of installed packages.
Privileged containers
For this feature to work, we'll need to run privileged containers, since we'll need to do mounts, and that requires root. So unfortunately we won't be using LXD's awesome security and isolation features for this container, but I figure that is a limitation I can live with for a development machine.
Also, remember that this will only work for the local case - the client can just as well connect to remote machines, but obviously your /home folder won't be present there. And you can't migrate the container either, of course.
With all these disclaimers out of the way, telling LXD that you want a privileged container is easy:
lxc launch ubuntu:xenial <container name> -c security.privileged=true
User mangling
The default Ubuntu images will give you a locked down machine with a single user, the ubuntu user, and no means to SSH into your new machine. You can however simply ask LXD to execute a command in your fresh container, and therefore can get a root shell there by executing /bin/bash.
We want our user inside the container to be called the same as the one outside the container, so we'll rename the ubuntu user to whatever the outside user is called.
Warning: This probably only works if your host's user has the same UID than the ubuntu user inside the container. This should be the case if your laptop/dev machine has a single user, but beware of this limitation.
Getting a shell inside the container is easy:
lxc exec <container name> /bin/bash
Tadaaa! Root!
Let's now rename the ubuntu user to whatever your user is called:
sed -i 's/ubuntu/<new user name>/g' /etc/{passwd,shadow,group,gshadow}
It feels a bit dirty but it should work. And of course, like one of my colleagues so eloquently said: "the beauty with containers is that if it doesn't work, you can trash them and start again" :)
Resetting the user password
The newly renamed ubuntu user has a locked password by default (a sane choice), so you might want to re-enable it from your in-container root shell before you log out:
passwd <new user name>
Mounting your home
LXD now includes a nifty feature allowing you to create "devices" and mount them into containers, and that is precisely what we'll use to mount our host's /home/ into the container's:
lxc config device add <container name> homedir disk source=/home/$USER path=/home/<new user name you chose at the previous step>
This should hopefully work its magic - and you can now try to either SSH login into your instance (because .authorized_keys form your /home should now be inside the container's /home folder too!), or inspect what happened with root again by executing /bin/bash.
As long as your UIDs stay in sync between the outside host and the inside container, you should be good to go.
Comments? Questions? Get in touch, or discuss on hackernews .