Remote Docker builds over SSH¶
BuildKit is a modern backend that powers Docker's build engine. This example shows how to set up a dedicated BuildKit instance in a Slicer VM for isolated, remote container builds.
Note
Whilst Slicer could be used to design a multi-tenant container builder this example is not intended for that use case.
The setup in this example is intended for use by a developer for building images with a faster remote machine, or a different OS/architecture to their machine.
Using a remote BuildKit instance in a Slicer VM provides several benefits:
- Isolation: Build processes are completely isolated from your host system
 - Resource control: Dedicated CPU and memory resources for builds
 - Security: Builds run in a sandboxed environment
 - Flexibility: Easy to scale up resources or create multiple build environments
 - Clean state: Each VM can be easily reset to a clean state
 
This example is very minimal and covers the basic setup. You can expand it according to your needs. In the next steps we are going to:
- Install and configure BuildKit automatically on first boot with a userdate script.
 - Set up Docker buildx to use the remote BuildKit instance.
 
VM configuration¶
The Slicer configuration is adapted from the walkthrough.
When you create the YAML file, name it buildkit.yaml.
We are going to use a userdata script to install and configure BuildKit on the first VM boot.
Add the userdata_file to the hostgroup section:
  host_groups:
  - name: buildkit
    userdata_file: ./buildkit.sh
For better build performance, consider increasing the VM resources:
    vcpu: 4
    ram_gb: 8
    storage_size: 25G
Customize the ssh_keys or github_user fields so you can connect to the BuildKit instance over SSH. The Docker buildx remote driver supports connection to a remote BuildKit instance over SSH.
BuildKit installation script¶
Create the buildkit.sh userdata script that will automatically install and configure BuildKit:
#!/usr/bin/env bash
# BuildKit installation and configuration script
# This script installs buildkitd, configures the buildkit group, and creates a systemd service
#!/usr/bin/env bash
set -euxo pipefail
# Install buildkit
arkade system install buildkitd
# Add a buildkit group
sudo groupadd buildkit
# Add ubuntu user to buildkit group
sudo usermod -aG buildkit ubuntu
# Systemd service for buidlkit (daemonized under systemd)
cat <<'EOF' | sudo tee /etc/systemd/system/buildkitd.service > /dev/null
[Unit]
Description=BuildKit Daemon
After=network.target
[Service]
Type=simple
ExecStart=/usr/local/bin/buildkitd --addr unix:///run/buildkit/buildkitd.sock --group buildkit
Restart=always
User=root
[Install]
WantedBy=multi-user.target
EOF
sudo systemctl daemon-reload
sudo systemctl enable --now buildkitd
Start the VM¶
Start the VM with the following command:
sudo -E slicer up ./buildkit.yaml
Configure Docker buildx¶
Once your VM is running and BuildKit is installed, you can configure Docker buildx to use it as a remote builder. For more information about Docker builders, see the Docker builders documentation.
Add VM to known hosts¶
First, add the Slicer VM to your SSH known hosts to avoid connection issues:
# Replace with your actual VM IP if different
ssh-keyscan 192.168.137.2 >> ~/.ssh/known_hosts
Create the remote builder¶
Create a new buildx builder instance that connects to your Slicer VM:
# Create a new builder named 'slicer' using the remote driver
docker buildx create \
  --name slicer \
  --driver remote \
  ssh://ubuntu@192.168.137.2
Verify the builder¶
Check that your new builder is available and working:
# List available builders
docker buildx ls
# Inspect the slicer builder for detailed information
docker buildx inspect slicer
When buildx can successfully connect to the builder, the status should show as running:
slicer          remote
 \_ slicer0      \_ ssh://ubuntu@192.168.137.2    running   v0.24.0    linux/amd64 (+3), linux/386
The inspect command will show additional details about supported platforms, driver configuration, and connection status.
Use the remote builder¶
Once your builder is configured and running, all builds executed with --builder slicer will run on the remote BuildKit instance instead of your local machine.
Create a simple Dockerfile:
FROM alpine:3.19
CMD ["echo", "Hello, BuildKit!"]
Build a container using your remote BuildKit instance:
# Build and tag an image using the remote builder
docker buildx build \
  --builder slicer \
  -t hello-buildkit \
  .
The remote builder supports all BuildKit features including multi-platform builds, build secrets, cache mounts, and advanced Dockerfile syntax. Build outputs, logs, and any artifacts are handled seamlessly as if building locally, but with the security and resource isolation benefits of the dedicated VM.
You can also set the remote builder as your default to avoid specifying --builder on every command:
docker buildx use slicer
Troubleshooting¶
If you're having trouble connecting to the remote builder:
- 
Check VM status: Ensure the VM is running and BuildKit service is active
# SSH into the VM and check service status ssh ubuntu@192.168.137.2 sudo systemctl status buildkitd - 
Verify SSH connectivity: Test SSH connection directly
ssh ubuntu@192.168.137.2 "echo 'SSH connection successful'" - 
Check BuildKit socket: Verify the socket is accessible
ssh ubuntu@192.168.137.2 "sudo -u ubuntu -g buildkit buildctl --addr unix:///run/buildkit/buildkitd.sock debug info" 
Further thoughts¶
This was a basic example to demonstrate how to run BuildKit isolated in a Slicer VM. Some ideas to explore further:
- TCP connection: Run BuildKit over TCP with mTLS in the VM to avoid SSH key management
 - Ephemeral VMs: Use the Slicer REST API to provision temporary VMs for each build, then destroy them.
 - BuildKit pools: Create pools of BuildKit instances for native multi-platform builds (avoiding QEMU emulation) and shared persistent caching.
 
The isolated nature of microVMs makes this approach particularly well-suited for enterprise build infrastructure where security, resource control, and clean environments are priorities.