Nomad Systemd-Nspawn driver
June 17, 2025 ยท View on GitHub
This is a task driver for Hashicorp Nomad to run
containers with systemd-nspawn.
Containers started via this driver will have private networking enabled by default and their machine ID will be set to the allocation ID of the started Nomad task.
Client requirements
- Nomad 1.4.0+ running as
root - Go 1.20
- Linux
systemd-nspawninstalled
Building the driver from source
Checkout this repository and simply run make.
$ git clone https://github.com/JanMa/nomad-driver-nspawn.git
$ cd nomad-driver-nspawn
$ make
Testing the driver
To execute the built-in test suite run
$ make test
Using the driver
To test the driver, run the Nomad agent in development mode with the following command
$ sudo nomad agent -dev -plugin-dir=$(pwd) -config=example/config.hcl
Minimal job example
task "debian" {
driver = "nspawn"
config {
image = "example/Debian/image"
resolv_conf = "copy-host"
}
}
Argument reference
The driver supports the following subset of possible arguments from systemd-nspawn, which
should cover a broad range of use cases:
-
boot- (Optional)true(default) orfalse. Search for an init program and invoke it as PID 1. Arguments specified incommandwill be used as arguments for the init program. -
ephemeral- (Optional)trueorfalse(default). Make an ephemeral copy of the image before staring the container. -
process_two- (Optional)trueorfalse(default). Start the command specified withcommandas PID 2, using a minimal stub init as PID 1. -
read_only- (Optional)trueorfalse(default). Mount the used image as read only. -
user_namespacing- (Optional)true(default) orfalse. Enable user namespacing features inside the container. -
private_users- (Optional). Controls how user namespacing is enabled. For this option to take effect,user_namespacingneeds to be set totrue. -
private_users_ownership- (Optional). Controls how to adjust the container image's UIDs and GIDs to match the UID/GID range chosen withprivate_users. For this option to take effect,user_namespacingneeds to be set totrue. -
command- (Optional) A list of strings to pass as the used command to the container.config { command = [ "/bin/bash", "-c", "dhclient && nginx && tail -f /var/log/nginx/access.log" ] } -
console- (Optional) Configures how to set up standard input, output and error output for the container. -
image- The image to be used in the container. This can either be the path to a directory, the path to a file system image or block device or the name of an image registered withsystemd-machined. A path can be specified as a relative path from the configured Nomad plugin directory. This option is mandatory. -
image_download- (Optional) Download the used image according to the settings defined in this block. Structure is documented below. -
pivot_root- (Optional) Pivot the specified directory to be the containers root directory. -
resolv_conf- (Optional) Configure how/etc/resolv.confis handled inside the container. -
user- (Optional) Change to the specified user in the container's user database. -
volatile- (Optional) Boot the container in volatile mode. -
working_directory- (Optional) Set the working directory inside the container. -
bind- (Optional) Files or directories to bind mount inside the container.config { bind { "/var/lib/postgresql" = "/postgres" } } -
bind_read_only- (Optional) Files or directories to bind mount read only inside the container.config { bind_read_only { "/etc/passwd" = "/etc/passwd" } } -
environment- (Optional) Environment variables to pass to the init process in the container.config { environment = { FOO = "bar" } } -
port_map- (Optional) DEPRECATED A key-value map of port labels. Works the same way as in the docker driver. Note:systemd-nspawnwill not expose ports to the loopback interface of your host.config { port_map { http = 80 } } -
ports- (Optional) A list of port labels. Works the same way as in the docker driver. Note:systemd-nspawnwill not expose ports to the loopback interface of your host.config { ports = ["http"] } -
capability- (Optional) List of additional capabilities to grant the container.config { capability = ["CAP_NET_ADMIN"] } -
network_veth- (Optional)true(default) orfalse. Create a virtual ethernet link between the host and the container. -
network_bridge- (Optional) Attach the virtual container interface to a host side bridge that must already exist. -
network_zone- (Optional) Start the container in the given network zone. Each container may only be part of one zone, but each zone may contain any number of containers.
The image_download block supports the following arguments:
url- The URL of the image to download. The URL must be of typehttp://,https://or a validdockerimage reference. This option is mandatory.verify- (Optional)no(default),signatureorchecksum. Whether to verify the image before making it available. This option has no effect when downloadingdockerimages.force- (Optional)trueorfalse(default) If a local copy already exists, delete it first and replace it by the newly downloaded image.type- (Optional)tar(default),rawordocker. The type of image to download.
Networking
The nspawn driver has support for host networking and also bridge mode
networking. It can therefore be used with Consul service mesh.
Plugin Options
-
enabled- Thenspawndriver may be disabled on hosts by setting this option tofalse(defaults totrue). -
volumes- Enable support for Volumes in the driver (defaults totrue).
An example of using these plugin options with the new plugin syntax is shown below:
plugin "nspawn" {
config {
enabled = true
volumes = true
}
}
Client Attributes
The nspawn driver will set the following client attributes:
-
driver.nspawn- Set totrueif systemd-nspawn is found and enabled on the host node and Nomad is running with root privileges. -
driver.nspawn.version- Version ofsystemd-nspawne.g.:244.