How to compile lxd-p2c to migrate physical servers to LXD containers

The lxd-p2c utility helps you to migrate your physical servers to LXD containers. Dan Mac Donald wrote a tutorial with practical instructions on how to perform such a migration. There has been a recent discussion on compiling lxd-p2c and I am summarizing here.

You would run lxd-p2c on a physical server that is to be migrated to a LXD container. It is preferable to avoid compiling it on that physical server, but rather use a static binary of the executable. By doing so, the executable would not have any dependencies for the system libraries of the physical server. You would just need to have the correct architecture (such as amd64 or i386).

You can either compile lxd-p2c statically yourself, or grab a pre-compiled static binary from the output of Github Actions. Select which alternative is suitable for you.

How to compile lxd-p2c

You can compile lxd-p2c in a LXD container, then take the executable and use it on the physical server. The source code is at Right now, the code has last been updated in August 2020. Therefore, if you already have a static executable that is more recent than this last modification date, then you can keep using it.

Let’s assume that you want to compile lxd-p2c for the amd64 architecture. We create a container with Ubuntu 20.04 for the amd64 architecture and then install the prerequisite packages. We install the Go language from the snap package. We then install dqlite from the PPA. Then, install are necessary development packages. Subsequently, we get (download) the source code, enter the LXD source directory and invoke the Makefile to build lxd-p2c. At the very end, we copy the static binary from the container to the host.

$ lxc launch ubuntu:20.04/amd64 mycontainer
Creating mycontainer
Starting mycontainer
$ lxc shell mycontainer
root@mycontainer:~# snap install go --classic
go 1.15.8 from Michael Hudson-Doyle (mwhudson) installed
root@mycontainer:~# add-apt-repository ppa:dqlite/stable
 Latest stable release of dqlite.
 More info:
Press [ENTER] to continue or Ctrl-c to cancel adding it.
root@mycontainer:~# apt install -y build-essential acl libacl1-dev libcap-dev liblxc1 liblxc-dev libsqlite3-dev libudev-dev libuv1-dev libdqlite-dev
root@mycontainer:~# go get -d -v (download)
created GOPATH=/root/go; see 'go help gopath'
root@mycontainer:~# cd go/src/
root@mycontainer:~/go/src/ make lxd-p2c
CGO_ENABLED=0 go install -v -tags netgo ./lxd-p2c
root@mycontainer:~/go/src/ cd ~/go/bin/
root@mycontainer:~/go/bin# ls -l
total 10176
-rwxr-xr-x 1 root root 16734206 Mar  5 15:47 lxd-p2c
root@mycontainer:~/go/bin# file lxd-p2c 
lxd-p2c: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), statically linked, Go BuildID=mLlFN3E5sy7UA0okZPn6/AK-bABIT6PoWOIM0H6w6/wJhKivbIEQuC2PDzFBgl/Kwl8hGmlisXHq2Ti2u8l, not stripped
root@mycontainer:~/go/bin# logout
$ lxc file pull mycontainer/root/go/bin/lxd-p2c lxd-p2c

You can then copy lxd-p2c to get it is needed and perform the migration.

Getting lxd-p2c from the Github Actions output

Github has Github Actions as an in-built tool for CI/CD (Continuous Integration/Continuous Delivery). LXD uses Github Actions. Therefore, you can grab a static binary of lxd-p2c from the artifacts of one of the Github Actions workflows. To be able to download the actual artifact, you just need to be logged in into your Github account.

First, visit Then, choose one of the recent workflows. Any with a green tick is good, because it means the workflow compiled successfully. In blue text is the git branch, therefore you can select either master or stable-4.0. We select the latter.

Github Actions for the LXD project

We have clicked on a workflow run.

On the same page, scroll towards the end of the page. If you use the scroll wheel, you will notice the page is awkward when scrolling. This is because the page has elements that capture the scroll events. If unsure, use the scroll bar to move to the end. You will see the following. In the Artifacts box, click on Linux in order to download a ZIP file with the binaries of both the lxc client and the lxd-p2c utility.

Here are the ZIP file contents.

Zip file contents with the lxd client utility and the lxd-p2c utility.


We have seen how to get hold of the lxd-p2c executable that is used to migrate a physical server into a LXD container. There are some posts already on practical advice on how to best perform the migration with this tool.

Permanent link to this article:


    • rob on May 23, 2021 at 15:23
    • Reply

    You may need to use ‘export GO111MODULE=off’ to force ‘go get’ to download sources.

    • Brian Candler on September 27, 2022 at 08:23
    • Reply

    This command has been replaced by lxd-migrate:

Leave a Reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.