Automatically install and configure the gVisor runsc
runtime on balenaOS hosts via a container. Simply add this service to your
docker-compose.yml and the runsc runtime becomes available for all containers
in your stack.
gVisor is an application kernel that provides an additional layer of isolation between running applications and the host operating system. It implements a substantial portion of the Linux system call interface in userspace, providing a sandbox that significantly reduces the attack surface compared to standard container runtimes.
Add this service to your docker-compose.yml:
version: "2"
services:
install-runsc:
build: .
volumes:
- runsc:/runtime
labels:
io.balena.features.dbus: "1"
io.balena.features.balena-socket: "1"
# Your application using gVisor
my-app:
image: nginx:alpine
runtime: runsc
depends_on:
- install-runsc
volumes:
runsc: {}The runsc runtime will be automatically registered and available after the
balena service restarts (happens automatically during installation).
Note: At the time of writing, the
runtime:instruction in docker-compose.yml is not supported by the balena supervisor. The example above shows the intended usage pattern once supervisor support is added. Until then, you can use the runtime with manualdocker runcommands on the host, or a runtime wrapper may be implemented as a workaround. See the Limitations section for more details.
The container downloads official gVisor binaries (runsc and
containerd-shim-runsc-v1) from Google's gVisor releases, verifies their
checksums, and copies them to a named volume at /runtime/bin/.
The installation script determines the actual host filesystem path of the volume
by parsing /proc/self/mountinfo. This resolves the container path /runtime
to the host path (e.g., /mnt/data/docker/volumes/1_runsc/_data).
A systemd drop-in configuration is created at
/run/systemd/system/balena.service.d/runsc.conf that:
- Adds the volume's host path to the balena service's
PATH - Registers the runtime with balena engine using
--add-runtime runsc=/path/to/runsc
The script uses D-Bus to communicate with systemd to reload the daemon configuration and restart the balena service, making the runtime immediately available.
Provides access to the host Docker socket, allowing the
container to run helper containers that mount the host /run directory
(read-write) to install systemd drop-in configuration files.
Without this, the container cannot create the systemd configuration needed to register the runtime with the balena engine.
Enables communication with the host's systemd over D-Bus, which is required to:
- Reload the systemd daemon (
systemctl daemon-reload) - Restart the balena service (
systemctl restart balena.service)
Without this, systemd wouldn't pick up the new runtime configuration, and the changes wouldn't take effect.
The volume persists the gVisor binaries at a path that:
- Survives container restarts
- Is accessible from the host filesystem at a predictable location
- Can be added to the host's
PATHso the balena engine can locate therunscbinary
The runtime binaries must be accessible from the host because Docker/balena
executes them outside the container context when starting containers with
runtime: runsc.
- The systemd drop-in is installed under
/run(not/etc), so it's cleared on reboot - On each start, it checks if the runtime is already registered and skips unnecessary writes
- The gVisor binaries persist in the named volume across restarts
- The
runtime:instruction is not currently supported by balena supervisor - The runtime is registered and available at the engine level, but cannot be specified declaratively in docker-compose.yml. Future supervisor releases may add this support, or a runtime wrapper container could be implemented as a workaround - Requires balenaOS (uses balena-specific labels and paths)
- Causes a brief interruption to the balena service during initial installation
- The systemd drop-in is cleared on reboot (the installer container will recreate it on next start)
- Some applications may not be compatible with gVisor's syscall implementation
- Performance overhead compared to native runc (trade-off for increased security)
balena-engine info | grep -A5 RuntimesYou should see runsc listed among available runtimes.
balena logs install-runscbalena run --runtime=runsc -it --rm ubuntu dmesgThis project is licensed under the Apache License 2.0 - see the LICENSE file for details.
Copyright 2025 Balena Ltd.
This project uses the following components:
- gVisor binaries: Apache License 2.0 (Copyright Google LLC)