A GitHub Action that runs your CI tests inside a Containarium box. Unlike GitHub-hosted runners, the box is a real Linux container you can SSH into, hand off to an agent, and keep alive on failure for post-mortem debugging.
Pin to a release tag (@v1) rather than @main:
- uses: FootprintAI/containarium-run@v1
with:
server: https://cloud.containarium.dev
token: ${{ secrets.CONTAINARIUM_TOKEN }}Don't have a token yet? See containarium.dev/#ci for the 5-minute Tier 0 path (signup + mint a token at cloud.containarium.dev/settings/api-tokens + paste into a GitHub Secret).
In your repo:
.github/workflows/test.yml
name: CI
on: [pull_request]
jobs:
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: FootprintAI/containarium-run@v1
with:
server: ${{ secrets.CONTAINARIUM_SERVER }}
token: ${{ secrets.CONTAINARIUM_TOKEN }}.github/containarium.yml
image: ubuntu-24.04
setup:
- apt-get install -y build-essential
- go mod download
test:
- go test ./...- Real Linux per job:
systemd, full networking, persistent filesystem during the run. - Debug on failure: when a test fails, the box stays alive for an hour and a comment is posted on your PR with an SSH command and an agent-box MCP URL. Connect from Claude Code, Cursor, or any MCP client and debug in place.
- Preview environments (optional): add a
serve:block tocontainarium.ymland the action exposes the port on a public HTTPS subdomain for the duration of the run.
How the box lifecycle, SSH identity model, and source transfer actually work (and why) — see docs/FLOW.md.
| Name | Required | Default | Description |
|---|---|---|---|
server |
No | https://cloud.containarium.dev |
Containarium server address (matches CLI's --server flag / CONTAINARIUM_SERVER env var). Point at your self-hosted instance if not using Cloud. |
token |
Yes | — | API token. Use a GitHub Actions secret. |
config |
No | .github/containarium.yml |
Path to the containarium config file in your repo. |
box-cpu |
No | 4 |
CPU cores for the box. Smaller boxes pack more parallel jobs per backend host (see docs/RUNNERS.md). A resources.cpu in containarium.yml overrides this per-role. |
box-memory |
No | 4GB |
Memory for the box. Overridden by resources.memory in containarium.yml. |
box-disk |
No | 50GB |
Disk for the box. Overridden by resources.disk in containarium.yml. |
ssh-ready-timeout |
No | 240 |
Seconds to wait for the box's sshd to accept SSH after it reaches RUNNING (a box can be RUNNING before the server has propagated its key). Raise it when many jobs create boxes in parallel — under a high-concurrency CI matrix, key propagation lags and the default window can be too short. |
cache-key |
No | — | (planned; not in v1) Cache key to reuse a warm box across runs (e.g. ${{ hashFiles('go.sum') }}). |
keep-on-failure |
No | true |
On test failure, keep the box alive for debug-ttl and post a debug comment on the PR. |
lease-ttl |
No | 20m |
Birth/lease TTL the box is created with and a background heartbeat renews while the job runs. Once the job ends — success, failure, cancellation, or the runner dying — the heartbeat stops and the box self-reaps within one window. The blanket leak guard: a cancelled/crashed job can't strand a box. Accepts 20m / 1h / 900s. |
debug-ttl |
No | 1h |
On failure, how long to keep the box alive for debugging before it self-reaps. Bounded by the daemon (max 7 days); never infinite. |
org-id |
No | — | Cloud org UUID. When set, debug-box endpoint info (SSH host/port/user, MCP URL, keep-alive deadline) is reported back to the cloud's CI dashboard on test failure so the /ci/runs/<id> panel renders real connection info. Skipped silently when empty — preserves backwards-compat for users who haven't run the onboarding wizard. |
ssh-host |
No | — | (stopgap) SSH host for the box. Normally unset — the create response's sshHost field supplies it (the cloud is the only party that knows it; the region code isn't the DNS label). Set this only if your cloud hasn't yet been configured to return sshHost. |
preview-domain |
No | — | Public hostname to route to the container when containarium.yml has a serve: block (e.g. pr-${{ github.event.pull_request.number }}.previews.example.com). Required by the CLI; when empty, the expose step is skipped with a log line (the serve command still runs inside the box, but no public route is wired). See #13 for the design discussion. |
| Name | When | Description |
|---|---|---|
box-id |
always | The Containarium box ID created for this run. |
preview-url |
when serve: block defined |
Public URL of the served app. |
debug-url |
on failure with keep-on-failure: true |
Agent-box MCP URL for interactive debugging. |
image: ubuntu-24.04 # required — base image
setup: # optional — runs once, build deps + caches
- <shell command>
test: # required — your actual test command
- <shell command>
serve: # optional — for PR preview environments
command: <shell command>
port: <int>
resources: # optional — right-size the box (see docs/RUNNERS.md)
cpu: <cores> # overrides the box-cpu action input
memory: <size> # overrides box-memory
disk: <size> # overrides box-diskThe core is three fields — image + setup + test; serve: and
resources: are the only optional blocks. Resist adding more in v1.x
unless the use case is universal.
Same Action, point server at your instance:
- uses: FootprintAI/containarium-run@v1
with:
server: https://containarium.your-company.internal:8080
token: ${{ secrets.CONTAINARIUM_TOKEN }}The Cloud token issuance flow lives at cloud.containarium.dev; for self-hosted, issue your own tokens via the platform admin CLI.
When the box is created, the action drops a small JSON file into
/workspace/.containarium/ci-context.json describing the CI run that
spawned it — repo, PR number/title/URL, commit SHA, branch, actor,
GitHub run URL, workspace path. On failure, the same file is refreshed
with the failing test name and the last ~50 lines of test output.
The companion agent-box
exposes this file as an MCP resource (containarium://ci-context) so an agent
connecting to a failing box has the full picture on its first turn —
no "what am I looking at?" round-trip required. A second resource
(containarium://ci-prompt) provides an opinionated playbook for
debugging failing CI runs inside Containarium boxes — read alongside
the context.
- Marketing site: containarium.dev
- OSS repo (CLI, daemon, agent-box): FootprintAI/containarium
- Cloud control plane: cloud.containarium.dev
- Issues / feedback: GitHub Issues