Skip to content

systemd-nspawn

Systemd-nspawn is a lightweight containerization tool included in the systemd suite, designed to create sandboxed environments for running isolated processes or entire operating systems. Unlike full container runtimes like Docker, nspawn leverages systemd's built-in capabilities to manage namespaces, cgroups, and process isolation, making it ideal for testing, development, or running untrusted code in a controlled environment. It operates by booting a minimal root filesystem and launching a systemd instance within it, allowing for fine-grained control over resource allocation and process isolation.


Setting Up a Container Environment

To use nspawn, you first need a root filesystem for the container. This can be created using tools like debootstrap (for Debian/Ubuntu) or tar archives. Below is an example workflow using debootstrap:

1. Create a Directory for the Container

mkdir -p /var/lib/mycontainer

2. Set Up the Root Filesystem

debootstrap --arch=amd64 bullseye /var/lib/mycontainer
This creates a minimal Debian Bullseye root filesystem in /var/lib/mycontainer.

3. Configure Systemd Units (Optional)

Create a systemd unit file (e.g., /etc/systemd/system/mycontainer.service) to define how the container should be started:

[Unit]
Description=My Container

[Service]
ExecStart=/usr/bin/nspawn --bind=/etc/resolv.conf:/etc/resolv.conf --tmpfs /tmp --network=host /var/lib/mycontainer
Restart=always
This example binds the host's DNS configuration, mounts a tmpfs for /tmp, and uses host networking.


Running and Managing Containers

Once the environment is prepared, you can launch the container using systemd-nspawn:

1. Start the Container

systemctl start mycontainer
This starts the container as defined in the unit file. You can also launch it interactively:
systemd-nspawn --bind=/etc/resolv.conf:/etc/resolv.conf --tmpfs /tmp --network=host /var/lib/mycontainer

2. Use Bind Mounts and tmpfs

Bind mounts allow sharing files between the host and container. For example:

--bind=/home/user/data:/data
Mounts /home/user/data from the host to /data in the container. Use --tmpfs to create temporary filesystems in memory.

3. Networking Options

  • --network=host: Share the host's network stack.
  • --network=bridge: Use a virtual bridge (default).
  • --network=none: Disable networking entirely.

Advanced Configuration and Security

1. Cgroups and Resource Limits

Use --cpu=2 or --memory=1G to limit CPU and memory usage. These parameters are passed to the container's cgroups.

2. Security Considerations

  • Namespaces: nspawn isolates processes, IPC, and network stacks by default.
  • SELinux/AppArmor: Enable these to restrict container privileges further.
  • User Namespaces: Use --user to run the container as a non-root user.

Troubleshooting Common Issues

  • Missing Libraries: Ensure all required binaries are present in the container's root filesystem.
  • Permission Errors: Use --bind to grant access to host files or adjust ownership.
  • Logs: Check container logs with:
    journalctl -u mycontainer
    

Key takeaways

  • systemd-nspawn provides lightweight sandboxing by leveraging systemd's isolation features.
  • Containers require a root filesystem and can be configured with bind mounts, tmpfs, and networking options.
  • Use systemd units to manage container lifecycle and resource limits.
  • Security is enhanced through cgroups, namespaces, and SELinux/AppArmor integration.
  • Debug with journalctl and ensure all dependencies are present in the container's environment.