Forkr gives you instant Linux sandbox environments. Each environment is a box: a persistent, isolated Linux system you create in seconds, run commands in, snapshot, and reach over the network. You drive Forkr with the 4kr CLI, which talks to a server called forkr-api. The server manages the underlying Kubernetes and filesystem state so you work with boxes, not infrastructure.
You’ll see the word fork in the brand name (Forkr), in the --fork flag (clone an existing box’s filesystem), and in some tooling. The user-facing noun for a sandbox is box — that’s what the CLI help and these docs use.

The mental model

A box is a Kubernetes Deployment running a single privileged runner container. The default runner image is ubuntu:24.04. When a box starts, the runner sets up a persistent root filesystem and chroots into it, then starts PID 1:
1

Mount the kernel interfaces

The runner mounts proc, sysfs, and the host /dev into the box’s filesystem, and bind-mounts /tmp, /run, /etc/resolv.conf, and /etc/hosts.
2

Set the hostname

The box hostname is set to <box>.<project>.
3

chroot and start PID 1

The runner runs chroot /volumes and starts tini as PID 1:
exec chroot /volumes /usr/bin/tini -s -- /bin/bash -lc "sleep infinity"
The persistent root filesystem is mounted at /volumes. Anything you write there survives across stops and resumes.

Persistent filesystems

Forkr keeps box state on a btrfs mount on the node. The layers build on each other through copy-on-write snapshots:
LayerRole
basesRead-only template subvolumes. A new box starts from a base.
rootsWritable btrfs snapshots created from a base — your box’s live root.
checkpointsRoot snapshots you capture and restore.
volumes, volume-checkpoints, volume-backupsData-volume state for disks you mount into boxes.
Because roots are snapshots of a base, creating a box is fast and cheap: you get a writable copy of a template without duplicating it.

The forkr-api server

forkr-api is an HTTP server that owns the Kubernetes and btrfs state and serves interactive transports:
  • REST routes under /v1/projects/{project}/boxes/{name} for box lifecycle.
  • WebSocket exec at …/exec/ws and console at …/console for running commands and attaching an interactive terminal. A non-WebSocket POST …/exec is also available.
For running commands inside a box, the server prefers a container-runtime path and falls back to Kubernetes exec. See the API reference for the full route surface.

Reaching boxes

Each box is published at a stable HTTPS hostname:
https://{box}.{domain}
That exact form applies to the default project. Boxes in other projects get a project-qualified hostname instead.
The deployment domain is set on the server via FORKR_DOMAIN (required; falls back to localhost only for local dev defaults).

Box-to-box networking

Boxes in the same project reach each other over DNS without publishing anything. Box Services are headless, so a box name resolves directly to the pod and any port is reachable:
  • Same project: reach another box by its bare name.
  • Different project: reach it by name.project.
Publishing is only for exposing a box to the public internet. In-cluster, box-to-box traffic needs no publishing.

Common commands

Once you have a target configured, the everyday workflow looks like this:
# Create a box from the default base
4kr create myapp

# Run a command in it
4kr exec myapp -- echo hello

# List your boxes
4kr list

# Open an interactive console
4kr console myapp

# Delete it
4kr delete myapp
A few flags worth knowing on 4kr create:
  • --base / -b — start from a specific base (default base is box-base).
  • --fork / -f — clone an existing box’s filesystem instead of a base (cannot combine with --base).
  • --data / -d — mount a data volume as NAME=/path[:ro|:rw].
  • --env / -e, --cpu, --memory, --project / -p.
The 4kr docs command prints the full “Using forkr” guide in your terminal.

Projects

Boxes live in a project. The CLI resolves the project in this order:
  1. --project / -p flag
  2. FORKR_PROJECT environment variable
  3. The current git repository’s root directory name
  4. default
You can address a box in another project with project:box (canonical) or project.box (shorthand).

Where to next

Quickstart

Install 4kr, deploy an environment, and publish your first box.

Boxes

The box lifecycle: create, exec, stop, resume, delete.

Environment

The runtime inside a box: filesystem layout, PID 1, DNS, and injected env vars.

Snapshots and bases

Capture box state as checkpoints and turn it into reusable bases.

Data volumes

Persistent disks you mount into one or more boxes.

Services

Run long-lived services and expose them at a public URL.