Are you still stuck using a VM and NFS to edit your website code?
Did you know you can run a fairly simple process inside a running VM that will convert it to an LXD container?

It took a bit of figuring out, but the reduced memory usage, increased speed and easier directory sharing make it will worth the effort.

This assumes an existing VM which you can already log into. The approximate steps required are:
1. Install lxd - I initially installed with apt, but its an older version, so probably better to install the snap instead.

$ sudo snap install lxd

2. Do initial setup for lxd, all defaults worked fine for me.

$ sudo lxd init

3. Ensure that the hosts lxd is accessible (I used 7443 as the default 8443 is used by OpenShift)

$ sudo lxc config set core.trust_password somepass
$ sudo lxc config set core.https_address :7443

4. Build the lxc-p2c binary - its built to be portable. The go commands may depend on your local setup:

$ go get -v -x
$ cd ~/go-packages/src/
$ make deps
$ make lxc-p2c

5. Start the existing VM - Virtualbox in this case:

$ VBoxManage startvm "Ubuntu 16.04" --type headless

6. Copy the binary into the VM:

$ rsync -avP ~/go-packages/bin/lxc-p2c

7. Login to the VM and stop any running processes (I forgot to do this, and it didn't cause any issues but it is a development VM. Newer Ubuntu's will likely be using systemctl):

$ ssh
$ sudo /etc/init.d/apache2 stop
$ sudo /etc/init.d/mysql stop
$ sudo /etc/init.d/rsyslog stop

8. Execute the command to actually create the container from the VM, use any IP on the host/LXD machine that the VM can access, you will be prompted to accept a certificate and to enter the password from step 3:

$ sudo ./lxd-p2c dev-container /

9. Wait for the copy to finish. It can take a while to copy, but gives decent feedback as it goes.

10. Once complete, stop the VM and enjoy that sweet speed and memory:

$ VBoxManage controlvm "Ubuntu 16.04" acpipowerbutton

11. Check if the lxc container was created:

$ sudo lxc list

12. Start the container:

$ sudo lxc start dev-container

13. Start bash in the container:

$ sudo lxc exec bash

14. There will be some changes probably required for ip address allocation, I found the address range by checking for it on the host:

$ ip route | grep lxd

15. Then setting that statically in the container:

$ lxc exec dev-container bash
$ vim /etc/network/interfaces

# Add something like this
auto eth0
iface eth0 inet static
# Save and exit
$ sudo reboot

If you had ssh access setup to the VM, it should work to the container as well, just the IP address will now be different

16. So this is all good, but what about NFS. Well, one of the cool things with LXD is you can mount path entries into the container directly. Before we can do that, we need to move the containers directory out of the way. Its a drupal/php development VM in my case, so /var/www is what needs to be moved:

$ lxc exec dev-container bash
$ cd /var/
$ mv www www.old
$ exit

17. Then we can do the mapping and a security change to disable the virtualization of the uid/gid values. This is a dev container, and the uid/gid entries are the same as my host machine, there are some other ways to handle this in the references below:

$ lxc stop dev-container
$ lxc config device add dev-container var-www disk source=~/my-dev-dir path=/var/www
$ lxc config set dev-container security.privileged true
$ lxc start dev-container

17. After that, /var/www in the container reflects changes instantly from the host, so it then makes sense to move the files to the newly shared directory and work from there on the host from then on:

$ lxc exec dev-container bash
$ cd /var/www/
$ rsync -avP /var/www.old/ .
$ exit

These steps or similar ones and some entries in /etc/hosts should have you fully converted from a VM to a lightweight LXD container!


References that assisted me when working through this:
A reddit thread

Live demonstration of lxd-p2c at FOSDEM 2018

This guide is already quite complete.

Mounting a local volume into a container

Some info on uid/gid issues that I didn't need, but might be helpful. Note that the snap stores its data in:


Basics for LXD