AI News HubLIVE
In-site rewrite5 min read

Show HN: Containarium – self-hosted sandbox for AI agents, MCP-native

Containarium is an open-source, self-hostable platform that provides persistent, isolated Linux containers for AI agents. It uses MCP-native integrations to allow agents to manage sandboxes, execute shell commands, and expose services. It runs on a single VM with LXC containers and includes features like GPU passthrough, multi-backend support, and a sentinel architecture for high availability.

SourceHacker News AIAuthor: hsin003

Notifications You must be signed in to change notification settings

Fork 10

Star 175

BranchesTags

Open more actions menu

Folders and files

NameName

Last commit message

Last commit date

Latest commit

History

300 Commits

300 Commits

.github

.github

api/swagger

api/swagger

cmd

cmd

configs

configs

deployments

deployments

docs

docs

hacks

hacks

internal

internal

mcp-registry-submission

mcp-registry-submission

pkg

pkg

proto/containarium/v1

proto/containarium/v1

scripts

scripts

terraform

terraform

test

test

web-ui

web-ui

.gitignore

.gitignore

CHANGELOG.md

CHANGELOG.md

CLAUDE.md

CLAUDE.md

IMPLEMENTATION-PLAN.md

IMPLEMENTATION-PLAN.md

LICENSE

LICENSE

Makefile

Makefile

README.md

README.md

buf.gen.yaml

buf.gen.yaml

buf.lock

buf.lock

buf.yaml

buf.yaml

go.mod

go.mod

go.sum

go.sum

Repository files navigation

The open-source, self-hostable, agent-native sandbox. Bring your own agent — Cursor, Claude Code, OpenCode, your own MCP client. We run the box.

agent: "create me a sandbox called 'blog'" → containarium create agent: "wire up SSH so I can reach it" → containarium ssh-config sync agent: "install Caddy on :8080 inside the box" → shell_exec (via agent-box MCP) agent: "expose that on blog.example.com" → containarium expose-port

curl https://blog.example.com → hello world

🎬 Watch the full 55s demo: youtu.be/IBDDD_tb8FY · 🌐 Live demo: helloworld.demo.containarium.dev

Why "agent-native"?

AI agents are increasingly the primary user of dev infrastructure. They want to build, install, deploy, and verify — not on the human's laptop (too noisy, too risky, too local) but on a sandbox that's:

Persistent: state survives between agent runs.

Isolated: a misbehaving install doesn't touch your machine.

Real: a full Linux environment with systemd, real networking, and the ability to host things on the open internet.

Driven by structured tools: not by an agent typing commands into a TTY hoping nothing scrolls off-screen, but by MCP — typed, bounded, safe.

That's the box Containarium gives you. It runs as a self-hosted single-host platform (one VM → many isolated LXC containers), exposes its admin surface over MCP, and ships a second MCP server that lives inside the container so the agent can shell_exec and edit files directly.

You bring the agent. We run the box.

Quick start

  1. Self-host on a fresh Ubuntu VM (5 minutes)

curl -fsSL https://raw.githubusercontent.com/footprintai/containarium/main/hacks/install.sh \ | sudo bash

That installs Containarium + Incus + dependencies, starts the daemon, and gives you a working API at http://localhost:8080.

  1. Create your first box

sudo containarium create alice --ssh-key ~/.ssh/id_ed25519.pub sudo containarium list

  1. Wire up SSH so ssh alice just works

containarium ssh-config sync

Adds entries to ~/.containarium/ssh_config.

Then add ONE line to ~/.ssh/config:

Include ~/.containarium/ssh_config

ssh alice # connects through the sentinel

  1. Point your agent at the box

In ~/.cursor/mcp.json or ~/.claude.json:

Now Claude Code, Cursor, or any MCP-speaking agent can call shell_exec, read_file, write_file, list_directory, move_file, delete_file directly inside Alice's container.

  1. Make it reachable on a public hostname

containarium expose-port alice \ --container-port 8080 \ --domain blog.example.com

Caddy on the sentinel terminates TLS for blog.example.com and forwards to alice-container:8080. curl https://blog.example.com hits whatever Alice has serving on port 8080.

The four primitives

Every action in Containarium has a CLI verb (canonical) AND an MCP tool (thin wrapper that delegates to the same Go function). See CLAUDE.md for the convention.

agent-box — in-the-box MCP server

Runs inside every container. Reached over stdio (typically wrapped by SSH on the client side). Exposes Linux-native operations:

Tool What it does

shell_exec Run a shell command, capture stdout/stderr/exit, bounded by timeout (default 30s, max 10min) and 256 KiB output cap

read_file Byte range OR head=N lines OR tail=N lines

write_file Atomic write with mkdirp (temp + rename)

list_directory Type/size/mtime, hidden filtering

move_file Atomic rename with mkdirp on destination

delete_file Single-file remove (refuses directories so recursive deletes go via shell_exec where blast radius is explicit)

Optional sandbox: when AGENTBOX_ROOT is set, every file-ops path is resolved against that root with a boundary-aware prefix check. Default unset = no constraint. See internal/agentbox/ for the Go implementation.

mcp-server — platform MCP server

Runs on the host. Exposes outside-the-box admin operations: create_container, list_containers, delete_container, start_container, stop_container, expose_port, get_metrics, get_system_info. See cmd/mcp-server/.

containarium CLI

Same surface as the platform MCP, plus deeper administration. Top-level verbs:

containarium create Create a new container containarium list List all containers containarium delete Delete a container containarium expose-port Expose container:port on a public hostname containarium ssh-config Generate self-contained ssh_config containarium route Manage proxy routes (low-level) containarium passthrough Manage TCP/UDP passthrough rules containarium token Issue JWT tokens for the API containarium info System info containarium version Print version

Run containarium --help for full options.

Sentinel — sshpiper + Caddy + PROXY-protocol

The sentinel is a tiny always-on VM (e2-micro on GCP free tier works) that:

Receives SSH on port 22 (sshpiper routes to the right backend by username).

Receives HTTPS on 443 (Caddy with TLS-passthrough or PROXY-protocol-aware forwarding to backend Caddy).

Survives spot-VM termination on the backend with a maintenance page.

Holds the static IP / DNS A-record so backends can be ephemeral.

See docs/SENTINEL-DESIGN.md for the full design.

Architecture

Agent (Cursor / Claude Code / OpenCode) | | MCP over stdio v ssh user@box → sshpiper → agent-box (in container) | | HTTPS v Sentinel (e2-micro, always-on) ├── sshpiper (port 22) : routes by username └── Caddy + PROXY-protocol (443) : routes by hostname | v +---------------------------+ | Backend VM (spot or | | bare-metal GPU node) | | | | Incus (LXC) ── containers | ├── alice-container : SSH + agent-box stdio MCP | ├── bob-container : SSH + agent-box stdio MCP | └── ... : ZFS-backed persistent storage | | | Caddy (per-backend) : TLS termination | Containarium daemon : container lifecycle, metrics +---------------------------+

A single sentinel can front multiple backend VMs — a "pool" — and a single deployment can run multiple pools (each isolated). See docs/MULTI-POOL.md.

How it's different

vs. SaaS-only sandboxes (e2b, Modal, Replit)

These give you sandboxes for AI agents, but only as hosted SaaS:

Self-hostability: Containarium runs on your own infrastructure (a $5 VM, your homelab, your enterprise data center). e2b, Modal, and Replit are SaaS-only — your code, your data, and your customers go through their compute.

License: Apache 2.0, no CLA. Fork it, sell it, run it.

Surface: full Linux containers with systemd, real network namespaces, GPU passthrough. Not a process-per-call sandbox.

Transport: MCP-native from day one, not a custom SDK with MCP bolted on.

vs. dev environment platforms (Codespaces, Gitpod, Coder)

Those are persistent IDEs. Containarium is a persistent box — agent-driven, not developer-driven, no IDE assumption, SSH-as-the-API:

Containarium environments are reached by SSH and MCP. Any IDE works (Vim, JetBrains Remote, VS Code Remote, Cursor's remote dev — your call).

Cost: no per-hour billing in the OSS path. Self-host costs are just your underlying VM.

Persistence: containers survive indefinitely; Codespaces auto-delete after inactivity.

vs. application container platforms (Docker, Kubernetes)

LXC is a system container, not an application container. Each container has systemd, a real init, real users, real package managers, real sudo. You can run Docker inside a Containarium container; the reverse isn't really a thing.

If your agent is going to apt install half a Linux distro, edit config files in /etc, run a database, and reboot — LXC is the right shape. If your agent runs a single Python process, Docker or Modal is fine.

What's in the box

Beyond the agent-native primitives, Containarium ships:

Multi-OS

Ubuntu 24.04 LTS (default)

Rocky Linux 9 (dev/test)

RHEL 9 (production)

Windows Server VMs via QEMU/KVM with RDP — see docs/WINDOWS-VM-SETUP.md

GPU passthrough

For ML/AI agent workflows. Works with NVIDIA RTX 3090, RTX 4090, and similar. PCI-level passthrough so the container sees the GPU directly. Tested on bare-metal GPU nodes connected to the sentinel via tunnel.

Multi-backend

A single sentinel can front:

GCP spot VMs: cost-effective cloud backends with auto-recovery on preemption.

Bare-metal GPU nodes: any Linux box you can SSH to; reaches the sentinel via outbound tunnel.

Windows VMs: live alongside Linux backends.

All containers from all backends appear in a single unified API.

Web UI

A basic dashboard at /webui/ for users who'd rather not type CLI: container list, lifecycle controls, metrics, browser-based terminal. Polished UI is intentionally a cloud-product concern — the OSS web UI is functional, not opinionated.

Persistent storage (ZFS)

Containers survive VM restarts and spot termination. ZFS handles compression, snapshots (daily by default, 30-day retention), and checksums.

Sentinel HA

The sentinel itself is e2-micro (free tier). It:

Detects spot preemption in ~10s, serves a maintenance page.

Restarts spot VMs automatically (~85s total recovery).

Holds the static IP, so DNS doesn't change as backends rotate.

Monitoring & observability

VictoriaMetrics + Grafana auto-provisioned. Per-container CPU, memory, disk, network. Alerting via webhooks. SSH audit logs per user.

Security primitives

Unprivileged LXC containers: container root ≠ host root.

Per-user proxy accounts: /usr/sbin/nologin on the sentinel, users can only proxy through to their container.

fail2ban per-user: an attack on Alice's account doesn't ban Bob.

ClamAV + Trivy scanning across all backends.

AppArmor profiles per container.

AGENTBOX_ROOT sandbox to constrain agent-box file ops at runtime.

CLI reference (essentials)

Container lifecycle

Create (Ubuntu 24.04, default)

containarium create alice --ssh-key ~/.ssh/id_ed25519.pub

Create with options

containarium create ml-dev \ --ssh-key ~/.ssh/id_ed25519.pub \ --gpu 0 \ --stack gpu \ --memory 16GB \ --cpu 4

Lifecycle

containarium list containarium info containarium start alice containarium stop alice containarium delete alice

Networking

Expose a container port on a public hostname

containarium expose-port alice \ --container-port 8080 \ --domain blog.example.com

Lower-level route management

containarium route add api.example.com --target 10.0.3.42:3000 containarium route list containarium route delete api.example.com

Raw TCP/UDP passthrough (no TLS termination)

containarium passthrough add --port 50051 \ --target-ip 10.0.3.150 --target-port 50051

SSH config

Print to stdout (preview)

containarium ssh-config show

Write to ~/.containarium/ssh_config (one-line Include to wire in)

containarium ssh-config sync containarium ssh-config sync --sentinel sentinel.example.com # via sentinel containarium ssh-config sync --identity ~/.ssh/containarium_ed25519

Authentication

Issue a JWT token (CLI-only; never exposed via API)

containarium token generate \ --username admin \ --roles admin \ --expiry 720h \ --secret-file /etc/containarium/jwt.secret

Use it

curl -H "Authorization: Bearer " http://localhost:8080/v1/containers

Deployment

Manual in

[truncated for AI cost control]