Skip to content
65 linesCodeBlameRaw

Pick any line to see why it is the way it is: the commit, the pull request and issue it came from, and what the agent was thinking.

Self-hosted runners on a person's own computer are sandboxes that nothing a job runs can get out of. `g1t-runner sandbox up|down|status|update [--json]` gives a Windows, macOS or Linux computer up to two capabilities, each a runner of its own: Linux jobs in a Linux VM the runner owns, where the runner's image runs under Sysbox and each job is a fresh container inside it (nested-container, three walls from the computer); and jobs native to Windows, each in a Windows Sandbox of its own, discarded after, with one read-only folder holding the harness (a new `vm` isolation level, also `g1t-runner register --native`). On Windows the VM is a WSL 2 distribution imported from the release's signed root filesystem: its wsl.conf turns off drives, Windows programs and Windows' PATH, and the supervisor inside unmounts what WSL shares with every distribution anyway (/mnt/wsl, where Docker Desktop keeps its sockets to Windows, WSLg, the GPU driver folders), refuses to run while anything of the computer's is reachable, and drops containers' traffic to the computer's address but for DNS. It needs no administrator once WSL is installed, and works on Windows 11 Home. On macOS the VM runs under vfkit and on Linux without Sysbox under QEMU with KVM, with no shared folders and nothing forwarded in (built and tested as commands, not yet run on those machines); on Linux with Sysbox no VM is needed. `status --json` reports the state, versions, isolation, the current job and a sentence when something is wrong, and each capability's availability with its cause and fix, for the desktop app. `update` drains the runner, swaps in the newest signed image and starts again without registering again. The sandbox's images are built from deploy/sandbox/Dockerfile by scripts/sandbox-image.mjs and listed with their SHA-256 in the release's signed manifest, beside the runner image's digest. The release workflow now builds its images on g1t's own machines (g1t-4core) rather than waiting forever for a self-hosted runner, registering QEMU for arm64 where the machine allows it and building amd64 alone with a warning where it does not, and signs and publishes once the images are built. The Runners page shows each runner's isolation (Sandboxed, VM per job, Shared Docker, Unsandboxed), which the API now returns as `isolation`. The Self-hosted runners guide has a new "Sandbox on your computer" section, with what it cannot stop.1# syntax=docker/dockerfile:1.7
2#
3# The sandbox's Linux: what `g1t-runner sandbox up` runs on a person's own
4# computer, in a VM of the runner's own (crates/runner/src/selfhosted/launcher/).
5# It holds a Docker Engine with Sysbox and the runner's binary; the runner
6# itself runs as the runner's image (deploy/runner/Dockerfile) under
7# `--runtime=sysbox-runc`, as on a Linux server, and each job is a container
8# inside that. Three walls from the computer: the job's container, the
9# runner's Sysbox container, and the VM.
10#
11# Two targets, built by scripts/sandbox-image.mjs for each release:
12#
13# wsl A root filesystem for a WSL distribution on Windows (`wsl --import`),
14# with /etc/wsl.conf turning off drives, Windows programs and PATH.
15# vm The same with a kernel and systemd, made into a disk for a VM on
16# macOS (vfkit) or Linux (QEMU) with no shared folders.
17#
18# Build context: this folder plus `g1t-runner`, the static Linux build for
19# the image's platform.
20
21FROM docker:28-dind AS docker
22
23FROM debian:bookworm-slim AS sysbox
24ARG TARGETARCH
25# Sysbox 0.7 or later: earlier ones cannot run runc 1.2's checks of /proc
26# inside a Sysbox container ("unsafe procfs detected"), which Docker 28's
27# runc does. Pinned by SHA-256.
28ARG SYSBOX_VERSION=0.7.1
29ARG SYSBOX_SHA256_AMD64=9d6d5484f980d0a17f86c492c1262015c2afb66280bdb97215b79fde6a0261c5
30ARG SYSBOX_SHA256_ARM64=04ca894ae0b53f0fa54eaacc173ce40363c9a95ea5450f773716a84ef650a69b
31ADD https://github.com/nestybox/sysbox/releases/download/v${SYSBOX_VERSION}/sysbox-ce_${SYSBOX_VERSION}.linux_${TARGETARCH}.deb /tmp/sysbox.deb
32RUN expected="$([ "$TARGETARCH" = arm64 ] && echo "$SYSBOX_SHA256_ARM64" || echo "$SYSBOX_SHA256_AMD64")" \
33 && echo "$expected /tmp/sysbox.deb" | sha256sum -c - \
34 && dpkg-deb -x /tmp/sysbox.deb /tmp/sysbox \
35 && mkdir -p /out && cp /tmp/sysbox/usr/bin/sysbox-runc /tmp/sysbox/usr/bin/sysbox-mgr /tmp/sysbox/usr/bin/sysbox-fs /out/
36
37FROM debian:bookworm-slim AS base
38# iptables: the engine's networks and the rules that keep jobs off the
39# computer; rsync and fuse3: Sysbox's; e2fsprogs and util-linux: the VM's
40# state disk.
41RUN apt-get update \
42 && apt-get install -y --no-install-recommends ca-certificates iptables rsync fuse3 procps kmod e2fsprogs util-linux \
43 && rm -rf /var/lib/apt/lists/* /var/cache/apt/* \
44 && mkdir -p /var/lib/g1t-sandbox/state /etc/docker
45COPY --from=docker /usr/local/bin/dockerd /usr/local/bin/containerd /usr/local/bin/containerd-shim-runc-v2 \
46 /usr/local/bin/runc /usr/local/bin/docker-proxy /usr/local/bin/docker-init /usr/local/bin/docker /usr/local/bin/
47COPY --from=sysbox /out/ /usr/local/bin/
48COPY --chmod=0755 g1t-runner /usr/local/bin/g1t-runner
49ARG IMAGE_VERSION=dev
50RUN echo "$IMAGE_VERSION" > /etc/g1t-sandbox-version
51
52FROM base AS wsl
53COPY wsl.conf /etc/wsl.conf
54
55FROM base AS vm
56# A kernel, an init, and the unit that runs the sandbox at boot. The VM's
57# console (hvc0) is where it says how it is (launcher/vm.rs reads it).
58RUN apt-get update \
59 && apt-get install -y --no-install-recommends systemd systemd-sysv "linux-image-cloud-$(dpkg --print-architecture)" \
60 && rm -rf /var/lib/apt/lists/* /var/cache/apt/* \
61 && echo g1t-sandbox > /etc/hostname \
62 && systemctl mask getty@tty1.service serial-getty@hvc0.service serial-getty@ttyS0.service
63COPY g1t-sandbox.service /etc/systemd/system/g1t-sandbox.service
64COPY vm-network.network /etc/systemd/network/80-g1t.network
65RUN systemctl enable g1t-sandbox.service systemd-networkd.service systemd-resolved.service