Skip to content

Commit 6caae52

Browse files
authored
feat: add local container provider
* feat: add local container provider * fix: harden local container bootstrap * fix: clean local container lease keys * fix: reject local container actions runners
1 parent 944dbe5 commit 6caae52

24 files changed

Lines changed: 1630 additions & 14 deletions

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
- Added explicit AWS Fast Snapshot Restore promotion support for hot developer-image AMIs via `crabbox image promote --fast-snapshot-restore --fsr-az <az>` and the AWS developer-image mint wrapper.
1212
- Added `crabbox image fsr-status` and the coordinator Fast Snapshot Restore status route for checking live AWS snapshot/AZ state after promotion.
1313
- Added a light/dark mode toggle to the Crabbox documentation site that defaults to the system color scheme, persists the choice in local storage, and applies before first paint to avoid a flash.
14+
- Added `provider: local-container` with `docker`, `container`, and `local-docker` aliases for local Linux container leases and optional desktop/browser/WebVNC smoke boxes through Docker-compatible runtimes such as Docker Desktop, OrbStack, and Colima.
1415

1516
### Changed
1617

README.md

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,9 @@ Supported providers:
3232
direct Linux VMs.
3333
- [Proxmox](docs/providers/proxmox.md) (`provider: proxmox`): direct Linux QEMU
3434
VM clones from private Proxmox VE templates.
35+
- [Local Container](docs/providers/local-container.md)
36+
(`provider: local-container`, alias `docker`): local Linux containers through
37+
a Docker-compatible runtime such as Docker Desktop, OrbStack, or Colima.
3538
- [Static SSH](docs/providers/ssh.md) (`provider: ssh`): existing Linux, macOS,
3639
Windows, or WSL2 hosts.
3740
- [exe.dev](docs/providers/exe-dev.md) (`provider: exe-dev`): exe.dev VMs
@@ -304,6 +307,21 @@ exeDev:
304307

305308
Authenticate with `ssh exe.dev`; VM creation requires an active exe.dev plan.
306309

310+
Optional local container:
311+
312+
```yaml
313+
provider: local-container
314+
localContainer:
315+
runtime: docker
316+
image: debian:bookworm
317+
workRoot: /work/crabbox
318+
```
319+
320+
`provider: docker` is an alias for `local-container`; the backend uses standard
321+
Docker-compatible CLI commands, so OrbStack works when it is the active Docker
322+
context. Add `--desktop --browser` for local Xvfb/XFCE/x11vnc/noVNC browser
323+
smoke tests before moving the same workflow to remote capacity.
324+
307325
Optional Islo sandbox:
308326

309327
```yaml

docs/README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -87,7 +87,7 @@ Pick whichever matches your intent:
8787
- **Start here:** [Getting started](getting-started.md), [How Crabbox Works](how-it-works.md), [Concepts and glossary](concepts.md).
8888
- **Get the mental model:** [Architecture](architecture.md), [Orchestrator](orchestrator.md).
8989
- **Use the CLI:** [CLI](cli.md), [Commands](commands/README.md), [Features](features/README.md), [Configuration](features/configuration.md), [Jobs](features/jobs.md), [Actions hydration](features/actions-hydration.md), [Capsules](features/capsules.md), [Checkpoints](features/checkpoints.md), [Browser portal](features/portal.md), [Telemetry](features/telemetry.md).
90-
- **Pick or add a target:** [Provider reference](providers/README.md), [Providers feature overview](features/providers.md), [Provider authoring](features/provider-authoring.md), [Provider backends](provider-backends.md), [AWS](providers/aws.md), [Azure](providers/azure.md), [Google Cloud](providers/gcp.md), [Hetzner](providers/hetzner.md), [Proxmox](providers/proxmox.md), [Parallels](providers/parallels.md), [Static SSH](providers/ssh.md), [Blacksmith Testbox](providers/blacksmith-testbox.md), [Namespace Devbox](providers/namespace-devbox.md), [Semaphore](providers/semaphore.md), [Sprites](providers/sprites.md), [Daytona](providers/daytona.md), [Islo](providers/islo.md), [E2B](providers/e2b.md), [Modal](providers/modal.md), [Tensorlake](providers/tensorlake.md), [Cloudflare](providers/cloudflare.md), [Interactive desktop and VNC](features/interactive-desktop-vnc.md).
90+
- **Pick or add a target:** [Provider reference](providers/README.md), [Providers feature overview](features/providers.md), [Provider authoring](features/provider-authoring.md), [Provider backends](provider-backends.md), [AWS](providers/aws.md), [Azure](providers/azure.md), [Google Cloud](providers/gcp.md), [Hetzner](providers/hetzner.md), [Proxmox](providers/proxmox.md), [Parallels](providers/parallels.md), [Local Container](providers/local-container.md), [Static SSH](providers/ssh.md), [Blacksmith Testbox](providers/blacksmith-testbox.md), [Namespace Devbox](providers/namespace-devbox.md), [Semaphore](providers/semaphore.md), [Sprites](providers/sprites.md), [Daytona](providers/daytona.md), [Islo](providers/islo.md), [E2B](providers/e2b.md), [Modal](providers/modal.md), [Tensorlake](providers/tensorlake.md), [Cloudflare](providers/cloudflare.md), [Interactive desktop and VNC](features/interactive-desktop-vnc.md).
9191
- **Operate it:** [Operations](operations.md), [Observability](observability.md), [Troubleshooting](troubleshooting.md), [Performance](performance.md).
9292
- **Set it up or audit it:** [Infrastructure](infrastructure.md), [Security](security.md), [Source Map](source-map.md).
9393

docs/features/README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ Read when:
3939
- [Google Cloud](../providers/gcp.md): GCP Compute Engine Linux SSH leases.
4040
- [Hetzner](hetzner.md): Linux-only managed Hetzner behavior, classes, and cleanup.
4141
- [Proxmox](../providers/proxmox.md): direct Proxmox VE Linux QEMU VM clones.
42+
- [Local Container](../providers/local-container.md): local Linux containers through Docker-compatible runtimes.
4243
- [Blacksmith Testbox](blacksmith-testbox.md): delegated Testbox backend behavior.
4344
- [Namespace Devbox](namespace-devbox.md): Namespace Devbox SSH leases with Crabbox sync/run.
4445
- [Namespace Devbox setup](namespace-devbox-setup.md): CLI install, auth token profile, and live checks.

docs/features/configuration.md

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -284,6 +284,29 @@ static:
284284
workRoot: /Users/steipete/crabbox
285285
```
286286

287+
### Local Container
288+
289+
```yaml
290+
provider: local-container
291+
localContainer:
292+
runtime: docker
293+
image: debian:bookworm
294+
user: crabbox
295+
workRoot: /work/crabbox
296+
cpus: 0
297+
memory: ""
298+
network: bridge
299+
```
300+
301+
`provider: docker`, `provider: container`, and `provider: local-docker` are
302+
aliases for `local-container`. The backend uses Docker-compatible CLI commands,
303+
so Docker Desktop, OrbStack, Colima, and similar local runtimes work when their
304+
Docker context is active.
305+
306+
Use `--desktop --browser` to bootstrap Xvfb, XFCE, x11vnc, noVNC/websockify,
307+
desktop input tools, screenshot tools, ffmpeg, and a packaged browser inside
308+
the container.
309+
287310
### Blacksmith Testbox
288311

289312
```yaml

docs/features/providers.md

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ Direct provider backends can also run without the Crabbox coordinator:
3030
```text
3131
proxmox Proxmox VE QEMU VM clones exposed as SSH leases
3232
parallels Parallels Desktop linked clones exposed as SSH leases
33+
local-container Local Linux containers and desktop/browser smoke boxes
3334
exe-dev exe.dev VMs exposed as SSH leases
3435
semaphore Semaphore CI jobs exposed as SSH leases
3536
namespace Namespace Devboxes exposed as SSH leases
@@ -50,6 +51,7 @@ tensorlake Tensorlake Firecracker sandboxes with delegated command execution
5051
- [Hetzner](../providers/hetzner.md): Linux-only managed provider behavior, classes, and cleanup.
5152
- [Proxmox](../providers/proxmox.md): direct Proxmox VE Linux QEMU VM clones.
5253
- [Parallels](../providers/parallels.md): direct local or remote Mac Parallels Desktop VM clones, named VM snapshot templates, and small Mac fleets.
54+
- [Local Container](../providers/local-container.md): local Linux containers and desktop/browser smoke boxes through Docker-compatible runtimes.
5355
- [Static SSH](../providers/ssh.md): existing Linux, macOS, and Windows SSH hosts.
5456
- [exe.dev](../providers/exe-dev.md): exe.dev VMs exposed as SSH leases.
5557
- [Blacksmith Testbox](../providers/blacksmith-testbox.md): delegated Testbox backend behavior.
@@ -179,6 +181,12 @@ and optional snapshot, starts it, discovers the guest IP through `prlctl`, then
179181
uses normal Crabbox SSH sync/run/release. It supports Linux, macOS, and Windows
180182
templates when the guest already exposes the matching SSH contract.
181183

184+
Use `--provider local-container` or `--provider docker` with a local
185+
Docker-compatible runtime for zero-cloud Linux smoke tests. The provider starts
186+
a labeled container, publishes SSH on loopback, syncs into the container over
187+
SSH, and removes it on `stop`. It does not bind-mount the repo or the Docker
188+
socket by default.
189+
182190
Crabbox can also wrap Blacksmith Testboxes with `provider: blacksmith-testbox`. That backend does not use the Crabbox broker or direct cloud credentials. It shells out to the authenticated Blacksmith CLI for `testbox warmup`, `run`, `status`, `list`, and `stop`, while Crabbox keeps local slugs, repo claims, config, and timing summaries. See [Blacksmith Testbox](blacksmith-testbox.md).
183191

184192
Crabbox can use Namespace Devboxes with `provider: namespace-devbox`. Namespace

docs/provider-backends.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -176,6 +176,7 @@ internal/providers/aws
176176
internal/providers/azure
177177
internal/providers/gcp
178178
internal/providers/proxmox
179+
internal/providers/localcontainer
179180
internal/providers/ssh
180181
internal/providers/blacksmith
181182
internal/providers/namespace
@@ -213,6 +214,7 @@ internal/providers/azure # Azure SSH lease backend
213214
internal/providers/gcp # Google Cloud SSH lease backend
214215
internal/providers/hetzner # Hetzner SSH lease backend
215216
internal/providers/proxmox # Proxmox VE SSH lease backend
217+
internal/providers/localcontainer # local Docker-compatible container SSH backend
216218
internal/providers/ssh # static SSH backend
217219
internal/providers/blacksmith # Blacksmith delegated backend
218220
internal/providers/namespace # Namespace Devbox SSH backend

docs/providers/README.md

Lines changed: 13 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ static SSH provider for existing machines.
1717
| [Hetzner](hetzner.md) | SSH lease | Linux | fast Linux capacity at low cost |
1818
| [Proxmox](proxmox.md) | SSH lease | Linux | private Proxmox VE QEMU VM templates |
1919
| [Parallels](parallels.md) | SSH lease | Linux, macOS, Windows | local or remote Mac Parallels template/fleet clones |
20+
| [Local Container](local-container.md) | SSH lease | Linux | zero-cloud Linux and desktop/browser smoke tests through Docker-compatible runtimes |
2021
| [Static SSH](ssh.md) | SSH lease | Linux, macOS, Windows | reusing an existing host |
2122
| [exe.dev](exe-dev.md) | SSH lease | Linux | disposable exe.dev VMs with Crabbox sync |
2223
| [Blacksmith Testbox](blacksmith-testbox.md) | delegated run | Linux | existing Blacksmith Testbox workflows |
@@ -47,6 +48,7 @@ default.
4748
```sh
4849
crabbox warmup --provider aws --class beast
4950
crabbox run --provider hetzner -- pnpm test
51+
crabbox run --provider docker -- pnpm test
5052
crabbox run --provider blacksmith-testbox --id tbx_123 -- pnpm test
5153
crabbox run --provider namespace-devbox --id blue-lobster -- pnpm test
5254
```
@@ -65,6 +67,8 @@ Proxmox and delegated providers do not use the Crabbox coordinator:
6567

6668
- Proxmox clones private QEMU VM templates through the Proxmox VE REST API.
6769
- Parallels clones local or remote Mac Parallels Desktop VMs through `prlctl`.
70+
- Local Container starts labeled Linux containers through a Docker-compatible
71+
local runtime such as Docker Desktop, OrbStack, or Colima.
6872
- exe.dev creates and deletes VMs through the exe.dev SSH API.
6973
- Blacksmith uses the authenticated Blacksmith CLI.
7074
- Daytona uses Daytona API and SDK/toolbox APIs.
@@ -84,11 +88,12 @@ Proxmox and delegated providers do not use the Crabbox coordinator:
8488
`portMappings["22"]` report the public TCP mapping, Crabbox reuses its
8589
normal SSH sync/run path against `root@<pod-ip>:<public-port>`.
8690

87-
Namespace Devbox and Semaphore are SSH lease providers that do not use the
88-
Crabbox coordinator. Namespace provisions through the authenticated `devbox`
89-
CLI; Semaphore provisions through the Semaphore REST API; Sprites provisions
90-
through the Sprites API and reaches SSH through `sprite proxy`; exe.dev
91-
provisions through `ssh exe.dev` and returns a normal VM SSH target.
91+
Local Container, Namespace Devbox, and Semaphore are SSH lease providers that do
92+
not use the Crabbox coordinator. Local Container provisions through `docker`;
93+
Namespace provisions through the authenticated `devbox` CLI; Semaphore
94+
provisions through the Semaphore REST API; Sprites provisions through the
95+
Sprites API and reaches SSH through `sprite proxy`; exe.dev provisions through
96+
`ssh exe.dev` and returns a normal VM SSH target.
9297

9398
## Feature Matrix
9499

@@ -100,6 +105,7 @@ provisions through `ssh exe.dev` and returns a normal VM SSH target.
100105
| Hetzner | yes | yes | yes | Linux VNC/code | yes | no |
101106
| Proxmox | yes | yes | yes | no | yes | no |
102107
| Parallels | yes | yes | yes | host-dependent | yes | no |
108+
| Local Container | yes | yes | yes | local VNC/WebVNC; no code | yes | no |
103109
| Static SSH | yes | resolves host | yes | host-dependent | yes | no |
104110
| exe.dev | yes | yes | yes | no | yes | no |
105111
| Blacksmith Testbox | yes | yes | no | no | no | yes |
@@ -116,8 +122,8 @@ provisions through `ssh exe.dev` and returns a normal VM SSH target.
116122
| RunPod | yes | yes | yes | no | yes | no |
117123

118124
Actions runner hydration requires a normal SSH lease on Linux and is core-over-SSH.
119-
Use AWS, Google Cloud, Hetzner, Proxmox, Parallels, Static SSH, exe.dev, Namespace Devbox,
120-
Semaphore, Sprites, or RunPod for that path.
125+
Use AWS, Google Cloud, Hetzner, Proxmox, Parallels, Static SSH, exe.dev,
126+
Namespace Devbox, Semaphore, Sprites, or RunPod for that path.
121127

122128
## Implementation
123129

docs/providers/local-container.md

Lines changed: 150 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,150 @@
1+
# Local Container Provider
2+
3+
Read when:
4+
5+
- choosing `provider: local-container`, `provider: docker`, or `provider: container`;
6+
- using Docker Desktop, OrbStack, Colima, Lima, or another Docker-compatible local runtime;
7+
- changing `internal/providers/localcontainer`.
8+
9+
Local Container is an SSH lease provider for Linux containers on the local
10+
machine. Crabbox uses the configured Docker-compatible CLI to start a labeled
11+
container, publish its SSH port on loopback, syncs the current checkout into the
12+
container over SSH, runs the command, and removes the container on stop.
13+
14+
## When To Use
15+
16+
Use Local Container when:
17+
18+
- you want a zero-cloud Linux smoke path;
19+
- the local Docker-compatible runtime is already warm;
20+
- you want a local visible desktop, browser, screenshot, or input smoke before
21+
spending cloud capacity;
22+
- you want the same Crabbox sync, logs, artifacts, scripts, and `ssh` workflow
23+
before moving to remote capacity.
24+
25+
Use AWS, Azure, Google Cloud, Hetzner, Proxmox, or another remote provider when
26+
you need stronger host separation, larger capacity, cross-OS coverage,
27+
coordinator-backed portal desktops, shared team infrastructure, or
28+
provider-owned cleanup.
29+
30+
## Quick Start
31+
32+
```sh
33+
docker info
34+
crabbox run --provider local-container -- pnpm test
35+
crabbox warmup --provider docker --slug local-smoke
36+
crabbox run --provider docker --id local-smoke -- pnpm test:changed
37+
crabbox ssh --provider docker --id local-smoke
38+
crabbox stop --provider docker local-smoke
39+
```
40+
41+
Desktop/browser smoke:
42+
43+
```sh
44+
crabbox warmup --provider docker --desktop --browser --slug local-ui
45+
crabbox desktop doctor --provider docker --id local-ui
46+
crabbox screenshot --provider docker --id local-ui --output desktop.png
47+
crabbox desktop click --provider docker --id local-ui --x 120 --y 120
48+
crabbox webvnc --provider docker --id local-ui
49+
```
50+
51+
`docker` is an alias for `local-container`. The provider talks only to the
52+
Docker-compatible CLI and daemon; it does not use Docker Desktop-specific APIs.
53+
OrbStack works when it is the active `docker` context.
54+
55+
## Config
56+
57+
```yaml
58+
provider: local-container
59+
localContainer:
60+
runtime: docker
61+
image: debian:bookworm
62+
user: crabbox
63+
workRoot: /work/crabbox
64+
cpus: 0
65+
memory: ""
66+
network: bridge
67+
```
68+
69+
Provider flags:
70+
71+
```text
72+
--local-container-runtime <path-or-name>
73+
--local-container-image <image>
74+
--local-container-user <user>
75+
--local-container-work-root <path>
76+
--local-container-cpus <n>
77+
--local-container-memory <size>
78+
--local-container-network <network>
79+
```
80+
81+
Environment overrides:
82+
83+
```text
84+
CRABBOX_LOCAL_CONTAINER_RUNTIME
85+
CRABBOX_LOCAL_CONTAINER_IMAGE
86+
CRABBOX_LOCAL_CONTAINER_USER
87+
CRABBOX_LOCAL_CONTAINER_WORK_ROOT
88+
CRABBOX_LOCAL_CONTAINER_CPUS
89+
CRABBOX_LOCAL_CONTAINER_MEMORY
90+
CRABBOX_LOCAL_CONTAINER_NETWORK
91+
```
92+
93+
## Behavior
94+
95+
1. `warmup` or a fresh `run` creates a per-lease SSH key.
96+
2. The provider runs `docker run -d` with Crabbox labels, loopback SSH port
97+
publishing, and public-key auth environment for the bootstrap script.
98+
3. The container installs `openssh-server`, `git`, `rsync`, `curl`, and `sudo`
99+
when the image is Debian/Ubuntu-compatible and missing those tools.
100+
4. With `--desktop`, the container installs and starts Xvfb, XFCE, x11vnc,
101+
xdotool, screenshot tools, ffmpeg, noVNC, and websockify without requiring
102+
systemd.
103+
5. With `--browser`, the container installs a real package-manager browser
104+
where the image provides one and writes `/var/lib/crabbox/browser.env`.
105+
6. Crabbox waits for SSH readiness, syncs tracked and nonignored files into
106+
`localContainer.workRoot`, and uses the normal SSH executor.
107+
7. `status`, `list`, and `stop` inspect or remove labeled containers.
108+
109+
## Limits
110+
111+
- Linux target only.
112+
- No Crabbox coordinator support; lifecycle is local to the machine running the
113+
CLI.
114+
- Desktop, browser, VNC, WebVNC, screenshot, video, and desktop input helpers
115+
are local-only. `webvnc` starts noVNC/websockify on the target and tunnels it
116+
over SSH; it does not use the authenticated Crabbox portal.
117+
- No code-server, Tailscale bootstrap, or native checkpoint support yet.
118+
- `warmup --actions-runner` is not supported; use normal `crabbox run` for
119+
local container smoke tests or a remote SSH provider for GitHub runner
120+
registration.
121+
- The Docker daemon is a powerful local capability. Do not treat this as the
122+
same host isolation boundary as a remote VM or microVM.
123+
- The current checkout is synced into the container by default. Crabbox does not
124+
bind-mount the repo or mount the Docker socket.
125+
- The default `debian:bookworm` image bootstraps packages on first start. Use a
126+
prebuilt image with SSH/Git/rsync/desktop/browser packages when startup time
127+
matters.
128+
129+
## Runtime Notes
130+
131+
The provider expects Docker-compatible behavior for:
132+
133+
- `docker run`;
134+
- `docker ps`;
135+
- `docker inspect`;
136+
- `docker rm`;
137+
- labels;
138+
- loopback port publishing.
139+
140+
That keeps the backend portable across Docker Desktop, OrbStack, Colima, and
141+
other runtimes that expose the standard Docker CLI. Remote Docker contexts are
142+
not the intended MVP path because Crabbox connects to the published SSH port
143+
from the local machine.
144+
145+
## Related
146+
147+
- [Provider reference](README.md)
148+
- [Static SSH](ssh.md)
149+
- [Sync](../features/sync.md)
150+
- [Provider backends](../provider-backends.md)

0 commit comments

Comments
 (0)