How to build Multipass images with Packer

Errors or typos? Topics missing? Hard to read? Let us know or open an issue on GitHub.

Custom images are supported by Multipass only on Linux.

Packer is a utility that lets you (re)build images to run in a variety of environments. Multipass can run those images too, provided some requirements are met (namely, the image has to boot on the hypervisor in use, and cloud-init needs to be available).

Setting up the build directory

The easiest way is to start from an existing Ubuntu Cloud Image, and the base project setup follows (you can click on the filenames to see their contents, meta-data is empty on purpose):

├── cloud-data
│   ├── meta-data
│   └── <a href="">user-data</a>
└── <a href="">template.json</a>

1 directory, 3 files

To specify a different image or image type, modify the iso_checksum and iso_url fields within template.json

Building the image

You will need to install QEMU and Packer (e.g. sudo apt install qemu packer), and from there you can run the following commands:

$ packer build template.json
$ multipass launch file://$PWD/output-qemu/packer-qemu --disk 5G
Launched: tolerant-hammerhead
$ multipass shell tolerant-hammerhead
ubuntu@tolerant-hammerhead ~:$ 

Customizing the image

Now the above works for you, delete the test instance with multipass delete --purge tolerant-hammerhead and edit the following section in the template.json file:

            "type": "shell",
            "inline": ["echo Your steps go here."]

Anything you do here will be reflected in the resulting image. You can install packages, configure services, anything you can do on a running system. You’ll need sudo (passwordless) for anything requiring admin privileges, or you could add this to the above provisioner to run the whole script privileged:

            "execute_command": "sudo sh -c '{{ .Vars }} {{ .Path }}'",

Next steps

Go to Packer’s documentation to learn about the QEMU builder, other provisioners and their configurations as well as everything else that might come in handy. Alternatively, you could extend user-data with other cloud-init modules to provision your image.

Join the discussion on the Multipass forum and let us know about your images!

Let us know how this worked for you and what you’d like to see next!


@carmine would love your eyes on this ;).

After this procedure, the resulting packer-qemu file size is three times the base image. Is this normal or am I missing something?


It should be possible to shrink/compress it. Have a look at this StackOverflow question.

Let us know how it went!

Sorry I forgot to post the answer when I found it. Adding below setting in template.json's builders’ section fixes the issue.

"disk_compression": true

Thanks for this great guide by the way. I completed my first usable images yesterday, will be posting them when I got the repository setup. I have several other issues/questions about this procedure, but I’m not sure where to post them. Should I continue under this thread?

Thanks, and sure, here’s a good place as any :slight_smile:

If you install a package that adds users or groups (such as docker) below line will make the service broken.

"for i in group gshadow passwd shadow subuid subgid; do mv /etc/$i- /etc/$i; done"

Right, this is a bit of a sledgehammer - it could probably be something like this instead:

sed -i '/^packer/d' /etc/{group,gshadow,passwd,shadow,subuid,subgid}'

For this to work on Mac/Windows we’ll need the ‘launch file://’ capabilities.

Now we’re stuck with:
launch failed: http and file based images are not supported

Trying to follow this instruction inside a freshly built 20.04 VM
I am stuck here:

ubuntu@test-gui:~/packer$ ./packer build template.json

Build 'qemu' errored: Failed creating Qemu driver: exec: "qemu-system-x86_64": executable file not found in $PATH

==> Some builds didn't complete successfully and had errors:
--> qemu: Failed creating Qemu driver: exec: "qemu-system-x86_64": executable file not found in $PATH

BTW, I am aware and have usually no problems with nested virtualization

How can i build Debian image? Or where can i find already builded (i need Debian Stretch)?

Any reason not to just run cloud-init clean to do the cleanup steps rather than trying to do it manually?

Same, any info on this?

Hi all, sorry for the late reply, not sure how all this activity flew under the radar.

Correct, this is only currently supported on Linux, but we want at least multipass-workflows to allow custom images built this way.

You need to install qemu, here’s where you can find it in Ubuntu.

The qcow2 images here should do.

I didn’t know about clean when I wrote this :slight_smile:.

It looks like there is still no way to launch custom images on Mac. Is that correct?

The pastebins for this tutorial require login, which is not great. It’s also not really clear to me what the requirements of a custom image are. I take it that cloud-init must be in the image, but is there anything else?

But without knowing how to launch custom images, I guess it doesn’t matter.