This guide covers the complete installation and configuration of ContainAI across all supported platforms. ContainAI provides isolated sandbox environments for AI coding agents using Sysbox system containers.
- Prerequisites
- What Gets Installed
- Platform-Specific Setup
- CLI Output Behavior
- Component Details
- Verification
- Troubleshooting Setup
- Updating ContainAI
- Uninstalling
Before running cai setup, ensure you have:
| Requirement | Version | Check Command |
|---|---|---|
| Bash | 4.0+ | bash --version |
| Docker CLI | Any recent | docker --version |
| jq | Any | jq --version |
| ripgrep (rg) | Any | rg --version |
| OpenSSH client | 7.3+ | ssh -V |
Note on Docker: Only the Docker CLI is required. On Linux/WSL2, ContainAI installs and manages its own dockerd bundle - you do not need Docker Engine or Docker Desktop installed. On macOS, ContainAI uses a Lima VM.
| Requirement | Version | Check Command |
|---|---|---|
| WSL2 kernel | 5.5+ | uname -r |
| systemd | Enabled | ps -p 1 -o comm= (should show systemd) |
| Ubuntu/Debian | Any supported release | lsb_release -a |
Enable systemd in WSL2 (if not already enabled):
# Add to /etc/wsl.conf
sudo tee /etc/wsl.conf << 'EOF'
[boot]
systemd=true
EOFThen restart WSL from PowerShell:
wsl --shutdown| Requirement | Version | Check Command |
|---|---|---|
| Kernel | 5.5+ | uname -r |
| systemd | Running | systemctl --version |
| Ubuntu/Debian | Any supported release | For auto-install; manual install for others |
| Requirement | Version | Check Command |
|---|---|---|
| macOS | 12+ | sw_vers |
| Homebrew | Any | brew --version |
| Lima | Installed by setup | limactl --version |
The cai setup command installs and configures multiple components. Here's what gets installed on each platform:
%%{init: {'theme': 'base', 'themeVariables': {
'primaryColor': '#1a1a2e',
'primaryTextColor': '#ffffff',
'primaryBorderColor': '#16213e',
'secondaryColor': '#0f3460',
'tertiaryColor': '#1a1a2e',
'lineColor': '#a0a0a0',
'textColor': '#ffffff',
'background': '#0d1117'
}}}%%
flowchart TB
subgraph Docker["Docker Layer"]
Daemon["containai-docker.service<br/>/var/run/containai-docker.sock"]
DaemonCfg["/etc/containai/docker/daemon.json"]
end
subgraph Sysbox["Sysbox Layer"]
Runtime["sysbox-runc"]
Mgr["sysbox-mgr"]
FS["sysbox-fs"]
end
subgraph Context["Docker Context"]
Ctx["containai-docker context<br/>Points to isolated socket"]
end
subgraph SSH["SSH Infrastructure"]
Key["~/.config/containai/id_containai"]
SSHCfg["~/.ssh/containai.d/*.conf"]
Known["~/.config/containai/known_hosts"]
end
subgraph User["User Configuration"]
Config["~/.config/containai/config.toml"]
end
Daemon --> Runtime
Runtime --> Ctx
Ctx --> Key
Key --> Config
style Docker fill:#1a1a2e,stroke:#16213e,color:#fff
style Sysbox fill:#0f3460,stroke:#16213e,color:#fff
style Context fill:#16213e,stroke:#0f3460,color:#fff
style SSH fill:#0f3460,stroke:#16213e,color:#fff
style User fill:#1a1a2e,stroke:#16213e,color:#fff
| Component | WSL2 | Native Linux | macOS |
|---|---|---|---|
| Docker daemon | Isolated containai-docker.service |
Isolated containai-docker.service |
Lima VM |
| Docker socket | /var/run/containai-docker.sock |
/var/run/containai-docker.sock |
~/.lima/containai-docker/sock/docker.sock |
| Docker config | /etc/containai/docker/daemon.json |
/etc/containai/docker/daemon.json |
Inside Lima VM |
| Sysbox install | GitHub releases (Ubuntu/Debian) | GitHub releases (Ubuntu/Debian) | Inside Lima VM |
| Sysbox services | systemd | systemd | Lima VM systemd |
| Context name | containai-docker |
containai-docker |
containai-docker |
On Linux and WSL2, ContainAI installs and manages its own Docker daemon bundle. This ensures consistent behavior across installations and enables atomic updates.
- Installed automatically: The dockerd bundle is installed during
cai setupon Linux/WSL2 - No system Docker required: You do not need Docker Engine or Docker Desktop installed on your system
- Versioned structure: Binaries are installed to
/opt/containai/docker/<version>/ - Stable symlinks: The systemd service uses
/opt/containai/bin/symlinks - Atomic updates: Updates swap symlinks atomically via
cai update
/opt/containai/
├── docker/
│ ├── 27.3.1/ # Previous version (kept for rollback)
│ │ ├── dockerd
│ │ ├── docker
│ │ ├── containerd
│ │ └── ...
│ └── 27.4.0/ # Current version
│ ├── dockerd
│ ├── docker
│ ├── containerd
│ └── ...
├── bin/ # Stable symlinks (systemd uses these)
│ ├── dockerd -> ../docker/27.4.0/dockerd
│ ├── docker -> ../docker/27.4.0/docker
│ └── ...
└── VERSION # Contains current version string
To check for and apply updates:
cai updateUpdates are applied atomically by swapping symlinks and restarting the containai-docker service.
Note: On macOS, ContainAI uses a Lima VM with its own Docker installation. The dockerd bundle is not used on macOS.
%%{init: {'theme': 'base', 'themeVariables': {
'primaryColor': '#1a1a2e',
'primaryTextColor': '#ffffff',
'primaryBorderColor': '#16213e',
'secondaryColor': '#0f3460',
'tertiaryColor': '#1a1a2e',
'lineColor': '#a0a0a0',
'textColor': '#ffffff',
'background': '#0d1117'
}}}%%
flowchart TD
Start["What OS?"]
Start -->|Windows| WSL["Use WSL2<br/>Ubuntu/Debian distro"]
Start -->|Linux| Linux{"Ubuntu/Debian?"}
Start -->|macOS| Mac["Lima VM<br/>(auto-installed)"]
Linux -->|Yes| Native["Native install<br/>cai setup"]
Linux -->|No| Manual["Manual Sysbox<br/>See Sysbox docs"]
WSL --> Setup["cai setup"]
Native --> Setup
Mac --> Setup
style Start fill:#1a1a2e,stroke:#16213e,color:#fff
style Setup fill:#0f3460,stroke:#16213e,color:#fff
style Manual fill:#e94560,stroke:#16213e,color:#fff
ContainAI installs and manages its own dockerd bundle on WSL2 - you do not need Docker Engine or Docker Desktop installed. The setup creates a completely isolated Docker daemon. Note that Docker Desktop integration mode is not supported (Sysbox requires a native Linux Docker daemon).
- Checks kernel version (requires 5.5+)
- Tests seccomp compatibility (WSL 1.1.0+ may have conflicts)
- Downloads and installs Sysbox from GitHub releases (Ubuntu/Debian)
- Downloads and installs dockerd bundle to
/opt/containai/docker/<version>/ - Creates isolated daemon config at
/etc/containai/docker/daemon.json - Creates dedicated systemd service
containai-docker.service - Starts isolated Docker daemon at
/var/run/containai-docker.sock - Creates Docker context
containai-docker - Sets up SSH infrastructure
Note: Your system Docker at /var/run/docker.sock is never touched (if present).
# Source ContainAI CLI
source /path/to/containai/src/containai.sh
# Run setup (silent by default)
cai setup
# Or with verbose output to see progress messages
cai setup --verbose
# If seccomp warning appears, use --force
cai setup --forceNote: Commands are silent by default (Unix Rule of Silence). Use
--verboseto see status messages during setup, or setCONTAINAI_VERBOSE=1for persistent verbosity. Warnings and errors always emit to stderr regardless of verbosity settings.
| Component | Path |
|---|---|
| Docker daemon config | /etc/containai/docker/daemon.json |
| Docker socket | /var/run/containai-docker.sock |
| Systemd service | /etc/systemd/system/containai-docker.service |
| Sysbox binaries | /usr/bin/sysbox-runc, /usr/bin/sysbox-mgr, /usr/bin/sysbox-fs |
| SSH key | ~/.config/containai/id_containai |
| SSH config dir | ~/.ssh/containai.d/ |
| User config | ~/.config/containai/config.toml |
| Known hosts | ~/.config/containai/known_hosts |
The setup creates an isolated Docker daemon that never touches system Docker. The configuration is stored at /etc/containai/docker/daemon.json:
{
"default-runtime": "sysbox-runc",
"runtimes": {
"sysbox-runc": {
"path": "/usr/bin/sysbox-runc"
}
},
"hosts": ["unix:///var/run/containai-docker.sock"],
"data-root": "/var/lib/containai-docker",
"exec-root": "/var/run/containai-docker",
"pidfile": "/var/run/containai-docker.pid",
"bridge": "cai0"
}During setup, the cai0 bridge is created and assigned 172.30.0.1/16 to avoid
subnet conflicts with system Docker.
The systemd service /etc/systemd/system/containai-docker.service runs a dedicated Docker daemon:
[Unit]
Description=ContainAI Docker Daemon (isolated)
After=network.target containerd.service sysbox.service
[Service]
ExecStart=/opt/containai/bin/dockerd --config-file=/etc/containai/docker/daemon.json
Restart=on-failure
[Install]
WantedBy=multi-user.targetContainAI can expose the isolated daemon to Windows via a named pipe. If npiperelay.exe is available in the Windows PATH, cai setup will:
If npiperelay.exe is missing, cai setup attempts to install it via winget.exe install jstarks.npiperelay.
- Install
socatin WSL (if needed) - Create and start the systemd service
containai-npipe-bridge.service - Configure the Windows Docker context
containai-dockerto use the named pipe:
docker --context containai-docker infoThe named pipe endpoint is npipe:////./pipe/containai-docker.
ContainAI installs and manages its own dockerd bundle on Linux - you do not need Docker Engine installed. The setup creates a completely isolated Docker daemon that never touches your system Docker installation (if present).
- Checks kernel version (requires 5.5+)
- Downloads and installs Sysbox from GitHub releases (Ubuntu/Debian only)
- Downloads and installs dockerd bundle to
/opt/containai/docker/<version>/ - Creates isolated daemon config at
/etc/containai/docker/daemon.json - Creates dedicated systemd service
containai-docker.service - Creates Docker context
containai-dockerpointing to isolated socket - Sets up SSH infrastructure
Note: Your system Docker at /var/run/docker.sock and /etc/docker/ is never touched (if present).
# Source ContainAI CLI
source /path/to/containai/src/containai.sh
# Run setup (silent by default)
cai setup
# Or with verbose output to see progress messages
cai setup --verboseFor distributions other than Ubuntu/Debian, install Sysbox manually following the official Sysbox installation guide.
# Download the appropriate package from GitHub releases:
# https://github.com/nestybox/sysbox/releases
# Install the downloaded package for your distribution
# Then run setup to configure Docker
cai setup| Component | Path |
|---|---|
| Docker daemon config | /etc/containai/docker/daemon.json |
| Docker socket | /var/run/containai-docker.sock |
| Systemd service | /etc/systemd/system/containai-docker.service |
| Sysbox binaries | /usr/bin/sysbox-runc, /usr/bin/sysbox-mgr, /usr/bin/sysbox-fs |
| SSH key | ~/.config/containai/id_containai |
| SSH config dir | ~/.ssh/containai.d/ |
| User config | ~/.config/containai/config.toml |
| Known hosts | ~/.config/containai/known_hosts |
macOS uses Lima to run a Linux VM with Docker and Sysbox. This provides the same isolation as native Linux.
- Installs Lima via Homebrew (if not present)
- Creates Lima VM
containai-dockerwith:
- Ubuntu 24.04 LTS
- Docker Engine
- Sysbox runtime
- Waits for Docker socket to be ready
- Creates Docker context
containai-dockerpointing to Lima socket - Sets up SSH infrastructure
# Source ContainAI CLI
source /path/to/containai/src/containai.sh
# Run setup (silent by default; may take several minutes for Lima VM creation)
cai setup
# Or with verbose output to see progress messages
cai setup --verbose| Component | Path |
|---|---|
| Lima VM | ~/.lima/containai-docker/ |
| Docker socket (via Lima) | ~/.lima/containai-docker/sock/docker.sock |
| Lima VM config | ~/.lima/containai-docker/lima.yaml |
| SSH key | ~/.config/containai/id_containai |
| SSH config dir | ~/.ssh/containai.d/ |
| User config | ~/.config/containai/config.toml |
| Known hosts | ~/.config/containai/known_hosts |
# Check Lima VM status
limactl list
# Start the VM (if stopped)
limactl start containai-docker
# Stop the VM
limactl stop containai-docker
# Shell into the VM
limactl shell containai-docker
# Delete the VM (removes all data inside VM)
limactl delete containai-dockerContainAI follows the Unix "Rule of Silence" - commands are silent by default and only produce output when there's something meaningful to report.
- Silent by default: Info and status messages are suppressed
- Warnings and errors always emit: Important messages always go to stderr
- Piping-friendly: Silent default allows clean piping and scripting
Use the --verbose flag (long form only) to see status messages:
# See progress during setup
cai setup --verbose
# See connection messages during shell
cai shell --verbose
# Verbose import
cai import --verboseOr set the environment variable for persistent verbosity:
# Enable for current session
export CONTAINAI_VERBOSE=1
cai setup
# Or per-command
CONTAINAI_VERBOSE=1 cai shellWhen multiple verbosity controls are specified:
--quietoverrides everything (suppresses info/step/ok messages)--verbosetakes next priority (enables info/step/ok messages)CONTAINAI_VERBOSE=1env var is the default fallback
Example:
# Quiet wins over env var
CONTAINAI_VERBOSE=1 cai shell --quiet # Silent
# --verbose enables output
cai setup --verbose # Shows progressThe -v short flag is not a verbose shorthand. This avoids conflicts with:
- Top-level
cai -vfor--version - Docker conventions where
-vmeans volume mount
Always use --verbose (long form) for verbosity.
The containai-docker Docker context points to the Sysbox-enabled Docker daemon:
# List contexts
docker context ls
# Use the context explicitly
docker --context containai-docker info
# Check runtime configuration
docker --context containai-docker info | grep -A5 RuntimesExpected output shows sysbox-runc in the runtimes list.
ContainAI generates a dedicated SSH key for container access:
# View the public key
cat ~/.config/containai/id_containai.pub
# Check SSH config directory
ls -la ~/.ssh/containai.d/
# Verify Include directive in ~/.ssh/config
grep -i "containai" ~/.ssh/configThe Include directive in ~/.ssh/config should look like:
Include ~/.ssh/containai.d/*.conf
On Linux/WSL2, Sysbox runs as systemd services:
# Check Sysbox services
systemctl status sysbox-mgr
systemctl status sysbox-fs
# View Sysbox version
sysbox-runc --versionAfter setup, verify the installation with cai doctor:
cai doctorThe output varies by platform, but key sections to look for:
ContainAI Doctor
================
Docker
Docker CLI: [OK]
Docker daemon: [OK]
Sysbox Isolation
Sysbox available: [OK]
Runtime: sysbox-runc [OK]
Context 'containai-docker': [OK] Configured
Platform: WSL2
Kernel version: 5.15 [OK]
Seccomp compatibility: ok [OK]
SSH
SSH key exists: [OK]
SSH config directory: [OK]
Include directive: [OK]
OpenSSH version: [OK] 8.9
| Status | Meaning |
|---|---|
[OK] |
Component working correctly |
[WARN] |
Minor issue, may still work |
[ERROR] |
Blocking issue, needs attention |
[INFO] |
Informational note |
[SKIP] |
Check skipped due to earlier failure |
# Verify Docker context works
docker --context containai-docker info
# Verify Sysbox runtime is available
docker --context containai-docker info | grep sysbox
# Test a Sysbox container
docker --context containai-docker run --rm --runtime=sysbox-runc alpine echo "Sysbox works!"
# Verify SSH key exists and has correct permissions
ls -la ~/.config/containai/id_containai
# Should show: -rw------- (600)
# Verify SSH config directory exists
ls -la ~/.ssh/containai.d/
# Should show: drwx------ (700)
# Verify Include directive
grep -i "include.*containai" ~/.ssh/configSymptom:
+==================================================================+
| *** WARNING *** |
+==================================================================+
| Sysbox on WSL2 may not work due to seccomp filter conflicts. |
Solution:
-
Proceed anyway (Sysbox often works despite the warning):
cai setup --force
-
Downgrade WSL to avoid seccomp conflicts:
wsl --update --web-download --version 1.0.3
Symptom:
[ERROR] Systemd is not running as PID 1 (found: init)
Solution:
Enable systemd in WSL:
# Edit /etc/wsl.conf
sudo tee /etc/wsl.conf << 'EOF'
[boot]
systemd=true
EOFThen restart WSL from PowerShell:
wsl --shutdownSymptom:
[ERROR] Permission denied accessing Docker
Solution:
Add your user to the docker group:
sudo usermod -aG docker $USER
newgrp docker # Apply immediately without logoutSymptom:
[ERROR] Sysbox auto-install only supports Ubuntu/Debian
Solution:
Install Sysbox manually for your distribution. See the Sysbox installation guide.
Symptom:
[ERROR] Failed to create Lima VM
Solution:
-
Check Homebrew is installed:
brew --version
-
Install Lima manually:
brew install lima
-
Try creating the VM manually:
limactl create --name=containai-docker limactl start containai-docker
Symptom:
Socket exists but docker info fails with permission denied.
Solution:
The setup should auto-repair this. If not, manually add user to docker group:
limactl shell containai-docker sudo usermod -aG docker $USER
limactl stop containai-docker
limactl start containai-dockerSymptom:
[ERROR] Kernel 5.4.0 is too old. Sysbox requires kernel 5.5+
Solution:
-
WSL2: Update WSL kernel:
wsl --update wsl --shutdown
-
Linux: Update your distribution or kernel.
Use cai update to apply updates to your ContainAI installation. The update process differs by platform and handles multiple components.
| Component | WSL2/Linux | macOS |
|---|---|---|
| dockerd bundle | Atomic symlink swap | N/A (Lima VM) |
| Sysbox runtime | Package upgrade | VM package update |
| Systemd unit | Template reconciliation | N/A |
| Docker context | Socket path update | Socket path update |
| Lima VM packages | N/A | apt-get upgrade |
# Preview what would be updated (no changes made)
cai update --dry-run
# Apply updates
cai updateUpdates to the dockerd bundle, sysbox, or systemd unit require restarting the containai-docker service. This stops all running ContainAI containers.
Default behavior when updates are pending and containers are running:
cai updateaborts with an actionable message listing the running containers- You must explicitly acknowledge container stoppage
# List running containers before update
docker --context containai-docker ps
# Proceed with container stop
cai update --stop-containers| Flag | Description |
|---|---|
--dry-run |
Preview changes without making any modifications |
--stop-containers |
Stop running containers before applying updates (Linux/WSL2) |
--force |
Skip confirmation prompts (e.g., VM recreation on macOS) |
--lima-recreate |
Delete and recreate Lima VM instead of in-place update (macOS only) |
WSL2 / Native Linux:
- Checks for running containers; aborts if found (unless
--stop-containers) - Updates systemd unit template if changed
- Updates Docker context if socket path changed
- Updates dockerd bundle if newer version available
- Updates sysbox if newer version available
- Restarts containai-docker service (when updates applied)
macOS (Lima):
- Updates Lima VM packages via
apt-get upgrade - Updates sysbox inside the VM if newer version available
- Checks if Lima template changed (hash mismatch or first update)
- If changed: prompts to recreate VM (containers will be lost)
--lima-recreateforces recreation regardless of template--forceauto-confirms recreation prompts
- Updates Docker context if socket path changed
Note: VM recreation is destructive - all containers inside the Lima VM are lost. Data in persistent volumes outside the VM is preserved.
ContainAI checks for updates by comparing:
- dockerd bundle: Local version in
/opt/containai/VERSIONvs latest from download.docker.com - Sysbox: Local
sysbox-runc --versionvs latest from GitHub releases - Systemd unit: Local unit content vs expected template
On macOS, sysbox version is queried inside the Lima VM via limactl shell.
The automatic update check runs before most cai commands (skipped for --help, --version, and in CI environments). To disable:
# Disable for current session (works with any cai command)
CAI_UPDATE_CHECK_INTERVAL=never cai <command>
# Disable permanently in config
# Add to ~/.config/containai/config.toml:
[update]
check_interval = "never"To remove ContainAI components, follow the manual cleanup steps below for your platform.
docker context rm containai-dockersudo systemctl stop containai-docker
sudo systemctl disable containai-docker
sudo rm -f /etc/systemd/system/containai-docker.service
sudo rm -rf /etc/containai/docker/
sudo rm -rf /var/lib/containai-docker/
sudo rm -f /var/run/containai-docker.sock
sudo systemctl daemon-reloadrm -rf ~/.ssh/containai.d/
rm -f ~/.config/containai/id_containai*
rm -f ~/.config/containai/known_hostsManually remove the Include line from ~/.ssh/config:
# Edit ~/.ssh/config and remove this line:
# Include ~/.ssh/containai.d/*.conflimactl stop containai-docker
limactl delete containai-dockerThe cleanup steps above do not remove:
~/.config/containai/config.toml(user configuration)- Docker images and volumes (remove with
docker image prune/docker volume prune) - Sysbox installation (remove with your package manager if desired)
- Architecture - System container architecture and design
- Configuration - Configuration file reference
- Troubleshooting - Comprehensive troubleshooting guide
- Security Comparison - How ContainAI compares to alternatives
- Sysbox Documentation - Sysbox runtime documentation