This plugin can build and provision systemd-nspawn containers. It can import or clone an existing base image, or generate one from scratch using debootstrap.
sudo apt-get install --no-install-recommends \
debootstrap golang-go libglib2.0-bin packer systemd-container zstd
git clone https://git.sr.ht/~angdraug/packer-builder-nspawn
cd packer-builder-nspawn
go build
packer build -only='*.base' .
Prerequisites:
debootstrap
to generate a minimal viable chroot imagegolang-go
to build this plugin from sourcelibglib2.0-bin
to monitor container status withgdbus
packer
(the Debian package recommends docker, you don't need that)systemd-container
systemd-nspawn and related tools- (optional)
packer-provisioner-apt
for installing deb packages - (optional)
zstd
for creating and importing .tar.zst images
In most cases, you'll want your container to be able to connect to the network to provision itself, for that you need to enable systemd-networkd and systemd-resolved:
systemctl enable systemd-networkd.service
systemctl start systemd-networkd.service
systemctl enable systemd-resolved.service
systemctl start systemd-resolved.service
The recommended way to install deb packages when provisioning images is packer-provisioner-apt. When installing that plugin from source, symlink it into your working directory so that Packer can find it:
cd ..
git clone https://git.sr.ht/~angdraug/packer-provisioner-apt
cd packer-provisioner-apt
go build
ln -s $(pwd)/packer-provisioner-apt ../packer-builder-nspawn
The included example nspawn.pkr.hcl
uses zstd to compress the image tarball,
it is several times faster than gzip at the same or better compression ratio.
You don't need zstd if you use a different method for archiving and delivering
your images.
For compatibility with the Debian package of Packer that is built with a newer
version of ugorji-go-codec than the one pinned
in Packer source, this plugin's go.mod
includes a replace line to import a
similarly patched version of Packer source. To use this plugin with Packer
built from unpatched upstream source, comment out that replace line.
In Debian, unprivileged user namespaces are disabled by default and have to be
enabled for nspawn's -U
option to have any effect:
echo kernel.unprivileged_userns_clone=1 > /etc/sysctl.d/nspawn.conf
systemctl restart systemd-sysctl.service
See discussion of this kernel feature and its security implications in Debian Wiki and Linux Weekly News.
This builder will work with and without private user namespaces. If you want an image built on a system with userns enabled to be usable on systems with userns disabled, use the method offered in systemd-nspawn(1) to reset chroot file ownership before archiving the image:
systemd-nspawn ... --private-users=0 --private-users-chown
All configuration options for this plugin are optional.
-
name
- Standard Packer build name parameter. The default is the builder namenspawn
. This will be used as container name and will be configured as the hostname within the container. -
import
- Import container image from a URL, file, or a directory tree, in a format recognized byimport-*
andpull-*
commands of machinectl(1). -
clone
- Name of a local container to clone. When neitherimport
norclone
options are set, a new image will be created with debootstrap(8). -
suite
- Distribution release code name as recognized by debootstrap(8). The default isunstable
. -
mirror
- URL for the distribution mirror. The default is https://deb.debian.org/debian. -
variant
- The bootstrap script variant as recognized by debootstrap(8). The default is to not pass--variant
to debootstrap, which will install required and important packages. Theminbase
variant will only install required packages, the plugin explicitly adds several small important packages to make sure that even aminbase
image has the CLI tools likely to be used in most provisioning scripts. -
cache_dir
- Absolute path to a directory where .deb files will be cached. The default is the host's APT cache at/var/cache/apt/archives
. -
machines_dir
- Absolute path to the directory where systemd-nspawn expects to find the container chroots. Unless you know what you're doing, keep the default/var/lib/machines
. -
timeout
- The timeout in seconds to wait for container startup and shutdown. The default is 20 seconds.
See nspawn.pkr.hcl for an example of how to build a minimal base container, archive it into a tarball, clone it a new container, and import a container image from the archived tarball.
Copyright (c) 2020 Dmitry Borodaenko angdraug@debian.org
This program is free software. You can distribute/modify this program under the terms of the GNU General Public License version 3 or later, or under the terms of the Mozilla Public License, v. 2.0, at your discretion.
This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0. If a copy of the MPL was not distributed with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
This Source Code Form is not "Incompatible With Secondary Licenses", as defined by the Mozilla Public License, v. 2.0.