Skip to content

Instantly share code, notes, and snippets.

@nathanblair
Last active November 11, 2025 22:32
Show Gist options
  • Select an option

  • Save nathanblair/e493a9cbc538979f9b9f2a72a53eefcd to your computer and use it in GitHub Desktop.

Select an option

Save nathanblair/e493a9cbc538979f9b9f2a72a53eefcd to your computer and use it in GitHub Desktop.
Minimal alpine with rootless buildit
minimumLimaVersion: 2.0.0
vmType: vz
arch: aarch64
cpus: 6
memory: 24 GiB
disk: 20 GiB
# The built-in containerd installer does not support Alpine currently.
# Use a provisioning script to install containerd, buildkit, and nerdctl.
#
# NOTE: Starting with Lima v2.0, nerdctl version must be v2.1.6 or later to
# enable port forwarding in rootful mode.
# Available in apk since Alpine 3.22.
containerd:
# Enable system-wide (aka rootful) containerd and its dependencies (BuildKit, Stargz Snapshotter)
# Note that `nerdctl.lima` only works in rootless mode; you have to use `lima sudo nerdctl ...`
# to use rootful containerd with nerdctl.
# 🟒 Builtin default: false
system: false
# Enable user-scoped (aka rootless) containerd and its dependencies
# 🟒 Builtin default: true (for x86_64 and aarch64)
# Set to false because Alpine doesn't have systemd and we're manually installing buildkit
user: false
upgradePackages: true
provision:
- mode: system
script: |
#!/bin/sh
set -eux
apk add --no-cache buildkit buildctl rootlesskit
# Setup subuid/subgid for rootless mode
# Give the user 65536 subordinate UIDs/GIDs starting at 100000
if ! grep -q "^{{.User}}:" /etc/subuid; then
echo "{{.User}}:100000:65536" >> /etc/subuid
fi
if ! grep -q "^{{.User}}:" /etc/subgid; then
echo "{{.User}}:100000:65536" >> /etc/subgid
fi
# Create /run/user directory for buildkitd (Alpine doesn't have systemd-logind)
mkdir -p /run/user/{{.UID}}
chown {{.UID}}:{{.UID}} /run/user/{{.UID}}
chmod 700 /run/user/{{.UID}}
- mode: user
script: |
#!/bin/sh
set -eux
# Create buildkit directory in home (Alpine doesn't have /run/user)
mkdir -p ~/.local/share/buildkit
# Start buildkitd in rootless mode with rootlesskit
rootlesskit --net=host \
buildkitd --addr unix://$HOME/.local/share/buildkit/buildkitd.sock \
--oci-worker-no-process-sandbox > ~/buildkitd.log 2>&1 &
echo $! > ~/buildkitd.pid
echo "buildkitd started in background (check ~/buildkitd.log for status)"
# When the "nestedVirtualization" feature is enabled:
# - Allows running a VM inside the guest VM.
# - The guest VM must configure QEMU with the `-cpu host` parameters to run a nested VM:
# qemu-system-aarch64 -accel kvm -cpu host -M virt
# - Without specifying `-cpu host`, nested virtualization may fail with the error:
# qemu-system-aarch64: kvm_init_vcpu: kvm_arch_init_vcpu failed (0): Invalid argument
# - Only supported on Apple M3 or later with `vmType: vz`.
# 🟒 Builtin default: false
nestedVirtualization: null
images:
- location: "https://dl-cdn.alpinelinux.org/alpine/v3.22/releases/cloud/nocloud_alpine-3.22.2-x86_64-uefi-cloudinit-r0.qcow2"
arch: "x86_64"
digest: "sha512:6dcb2ec1ac3ff160f1a2609fbd7cb8417df6c1c937c259238090d5bc494778924c0eb360c926d90bfbe7d0176692ae00b049f4a06d5070618a3b087a47c96532"
- location: "https://dl-cdn.alpinelinux.org/alpine/v3.22/releases/cloud/nocloud_alpine-3.22.2-aarch64-uefi-cloudinit-r0.qcow2"
arch: "aarch64"
digest: "sha512:481ad2db4fe024dd5d2dddd2abf2f722b738173c9ff6b76425ee877706bd49e26b2877ccae7b389aebae1d5e8df0384cc3c8355fc903378997340ce6c1b85faf"
mountType: virtiofs
# mounts:
# - location: "~"
networks:
# The "vzNAT" IP address is accessible from the host, but not from other guests.
# Needs `vmType: vz`
- vzNAT: true
portForwards:
- guestSocket: "{{.Home}}/.local/share/buildkit/buildkitd.sock"
hostSocket: "{{.Dir}}/sock/buildkitd.sock"
probes:
- mode: readiness
description: "buildkitd is running and healthy"
script: |
#!/bin/sh
set -eux
if ! buildctl --addr unix://{{.Home}}/.local/share/buildkit/buildkitd.sock debug workers >/dev/null 2>&1; then
echo >&2 "buildkitd is not running or not responding"
exit 1
fi
hint: |
buildkitd is not running or not healthy.
Check logs: limactl shell builder cat ~/buildkitd.log
Check process: limactl shell builder ps aux | grep buildkit
vmOpts:
vz:
rosetta:
# Enable Rosetta inside the VM; needs `vmType: vz`
# Hint: try `softwareupdate --install-rosetta` if Lima gets stuck at `Installing rosetta...`
# 🟒 Builtin default: false
enabled: true
# Register rosetta to /proc/sys/fs/binfmt_misc
# 🟒 Builtin default: false
binfmt: true
# User to be used inside the VM
user:
# User name. An explicitly specified username is not validated by Lima.
# 🟒 Builtin default: same as the host username, if it is a valid Linux username, otherwise "lima"
name: null
# Full name or display name of the user.
# 🟒 Builtin default: user information from the host
comment: null
# Numeric user id. It is not currently possible to specify a group id.
# 🟒 Builtin default: same as the host user id of the current user (NOT a lookup of the specified "username").
uid: null
# Home directory inside the VM, NOT the mounted home directory of the host.
# It can use the following template variables: {{.Name}}, {{.Hostname}}, {{.UID}}, {{.User}}, and {{.Param.Key}}.
# 🟒 Builtin default: "/home/{{.User}}.linux"
home: null
# Shell. Needs to be an absolute path.
# 🟒 Builtin default: "/bin/bash"
shell: null
video:
# QEMU display, e.g., "none", "cocoa", "sdl", "gtk", "vnc", "default".
# Choosing "none" will hide the video output, and not show any window.
# Choosing "vnc" will use a network server, and not show any window.
# Choosing "default" will pick the first available of: gtk, sdl, cocoa.
# As of QEMU v6.2, enabling anything but none or vnc is known to have negative impact
# on performance on macOS hosts: https://gitlab.com/qemu-project/qemu/-/issues/334
# 🟒 Builtin default: "none"
display: null
# VNC (Virtual Network Computing) is a platform-independent graphical
# desktop-sharing system that uses the Remote Frame Buffer protocol (RFB)
vnc:
# VNC display, e.g.,"to=L", "host:d", "unix:path", "none"
# By convention the TCP port is 5900+d, connections from any host.
# 🟒 Builtin default: "127.0.0.1:0,to=9"
display: null
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment