aibox

October 17, 2025 · View on GitHub

A secure Docker environment for running multiple AI CLIs (Claude Code, Codex, and Gemini) with isolation from the host system and support for multiple accounts.

Important: Make sure Docker and Docker Compose are installed and running before using this setup.

Features

  • Multi-CLI Support: Run Claude Code, Codex, or Gemini CLI from a single container
  • Security: Runs as a non-root user (ai) without sudo privileges for maximum isolation
  • Customizable: Configurable username and working directory via environment variables
  • Isolation: Complete filesystem isolation from host machine
  • Multi-Account Support: Manage multiple AI CLI accounts/configurations
  • Persistent Storage: Configurations persist across container restarts (mapped from host)
  • Resource Limits: CPU and memory limits to prevent resource exhaustion
  • Git Integration: Seamless git operations with SSH key mounting
  • Container Reuse: Automatically reuses existing containers with docker-compose up -d
  • Simplified Management: Single service architecture using docker-compose

Quick Start

1. Initial Setup

# On first run, aibox automatically pulls the Docker image from ghcr.io
# and creates a default profile at ~/.aibox/profiles/default.env
aibox

# Edit your profile if needed
nano ~/.aibox/profiles/default.env

Note: The Docker image is automatically pulled from the GitHub Container Registry (ghcr.io/zzev/aibox) on first use.

2. Run AI CLI

# Default: Opens interactive bash shell
aibox

# Run Claude Code directly
aibox --dangerously-skip-permissions

# Run Codex directly (executes codex CLI)
aibox -t codex

# Run Gemini directly (executes gemini CLI)
aibox -t gemini

# YOLO mode (skip all permissions - unified syntax)
aibox --yolo                          # Claude with --dangerously-skip-permissions
aibox -t codex --yolo                 # Codex with --sandbox danger-full-access
aibox -t gemini --yolo                # Gemini with --yolo

# Run specific CLI with arguments
aibox -t codex help
aibox -t gemini chat "Hello"

# Clean orphan containers before running
aibox --clean

# Check for Docker image updates
aibox --update

# Attach to existing running container
aibox --attach

3. Interactive Shell

# By default, the script opens an interactive shell
aibox

# Inside the container, you can run any CLI
claude --dangerously-skip-permissions
codex
gemini

Multi-CLI Usage

The container includes all three AI CLIs. Choose which one to run:

# Claude Code with arguments
aibox --dangerously-skip-permissions
aibox chat "Help me understand this codebase"

# Codex CLI - executes codex directly
aibox -t codex
aibox -t codex help

# Gemini CLI - executes gemini directly
aibox -t gemini
aibox -t gemini chat "Hello"

# YOLO mode (unified syntax across all CLIs)
aibox --yolo                          # Uses default CLI (usually claude)
aibox -t codex --yolo                 # Codex in YOLO mode
aibox -t gemini --yolo                # Gemini in YOLO mode

# Or use environment variable
AI_CLI=codex aibox
AI_CLI=gemini aibox

Each CLI uses its own configuration directory:

  • Claude: ~/.claude
  • Codex: ~/.codex
  • Gemini: ~/.gemini

All three are mapped from your host machine for persistence.

Multi-Account Management

Profiles are stored globally in ~/.aibox/profiles/ and work across all your projects.

# Profiles are created automatically on first use
aibox -a work -t codex        # Creates ~/.aibox/profiles/work.env if it doesn't exist
aibox -a personal             # Creates ~/.aibox/profiles/personal.env if it doesn't exist

# Or create manually
cp ~/.aibox/profiles/default.env ~/.aibox/profiles/work.env
nano ~/.aibox/profiles/work.env

cp ~/.aibox/profiles/default.env ~/.aibox/profiles/client.env
nano ~/.aibox/profiles/client.env

# List existing profiles
ls -1 ~/.aibox/profiles/*.env | xargs -n 1 basename

Benefits of centralized profiles:

  • Configure once, use across all your projects
  • No per-project setup required
  • Easy to switch between profiles
  • Keeps your repositories clean

Each profile maintains its own:

  • Git author/committer configuration
  • SSH key preferences
  • AI CLI preference (claude/codex/gemini)
  • Container settings

Command Options

aibox [OPTIONS] [CLI_ARGS]

OPTIONS:
  -t, --type TYPE        Choose CLI type: claude, codex, gemini (default: claude)
  -a, --account NAME     Use a specific account (default: 'default')
  -p, --setup NAME       Configure or reconfigure a profile
  -s, --shell            Start an interactive shell
  -c, --command CMD      Run a specific command
  -r, --remove           Remove container after exit
  --yolo                 Run CLI in YOLO mode (skip all permissions)
  --clean                Clean orphan containers before running
  --attach               Attach to existing container if running
  --update               Check for Docker image updates
  -h, --help             Show help message

File Structure

Installation directory (where aibox is installed):

.
├── Dockerfile                  # Docker image definition
├── docker-compose.yml          # Docker Compose configuration
├── bin/
│   └── aibox.js                # CLI entry point
├── src/                        # CLI implementation
├── scripts/
│   └── docker-entrypoint.sh    # Container entrypoint with git config and SSH fix
└── .aibox-profile.example.toml # Profile template

User configuration directory (~/.aibox/):

~/.aibox/
└── profiles/
    ├── default.toml            # Default profile (auto-created)
    ├── work.toml               # Work profile (optional)
    └── personal.toml           # Personal profile (optional)

Project directory (your code):

your-project/
├── .env                        # Optional: Base environment variables
└── .env.local                  # Optional: Local environment overrides

Environment Variables

Key environment variables in profile files (~/.aibox/profiles/*.toml):

  • AI_ACCOUNT: Account identifier (default: default)
  • AI_CLI: CLI type to use (claude, codex, or gemini)
  • ENV_FILE: Specify which .env file to use (auto-detects .env.local or .env if not specified)
  • GIT_AUTHOR_NAME: Git commit author name (automatically configured on container start)
  • GIT_AUTHOR_EMAIL: Git commit author email (automatically configured on container start)
  • GIT_COMMITTER_NAME: Git committer name (defaults to GIT_AUTHOR_NAME if not set)
  • GIT_COMMITTER_EMAIL: Git committer email (defaults to GIT_AUTHOR_EMAIL if not set)
  • SSH_KEY_PATH: Path to SSH keys directory (default: ~/.ssh)
  • SSH_KEY_FILE: Specific SSH key file to use (e.g., id_rsa_personal, id_rsa_work)

Using Different Environment Files

Environment files are optional. aibox will automatically detect and load them in this priority order:

  1. .env.local (if exists)
  2. .env (if exists)
  3. None (continues without project-specific env vars)

You can override this behavior by explicitly specifying a file:

# Auto-detect (default behavior)
aibox

# Use specific .env file
ENV_FILE=.env.production aibox -t codex

# Use .env.staging
ENV_FILE=.env.staging aibox -t gemini

# Use .env.test
ENV_FILE=.env.test aibox

Note: If you explicitly specify an ENV_FILE that doesn't exist, aibox will fail with an error. Auto-detection never fails.

SSH Key Configuration

SSH keys are automatically mounted from your host system:

# Use default SSH keys (mounts ~/.ssh directory)
aibox

# Use specific SSH key for work account
SSH_KEY_FILE=id_rsa_work aibox -a work -t codex

# Combine with environment file specification
SSH_KEY_FILE=id_rsa_work ENV_FILE=.env.production aibox

How it works:

  • Your ~/.ssh directory is mounted read-only in the container
  • macOS-specific SSH config options (UseKeychain) are automatically filtered out
  • A cleaned SSH config is created in /tmp/ssh_config_clean without macOS options
  • Git uses a custom SSH wrapper (/tmp/ssh-wrapper) that uses the cleaned config
  • When SSH_KEY_FILE is specified, Git is configured to use that specific key
  • The script warns if the specified key file doesn't exist

Security Features

  1. Non-root User: All CLIs run as ai user (UID 1001) without any sudo privileges
  2. Capability Dropping: Container drops all Linux capabilities except essential ones
  3. No New Privileges: Prevents privilege escalation
  4. Read-only Mounts: SSH keys mounted as read-only (config is filtered, not modified)
  5. Network Isolation: Runs in isolated Docker network (ai-network) with host access via host.docker.internal
  6. Resource Limits: CPU (2 cores max) and memory (4GB max) limits
  7. SSH Config Filtering: Automatically removes incompatible macOS options for Linux compatibility

Volume Persistence

The following data persists across container restarts (mapped from host):

  • Claude Config: ~/.claude (mapped from host ~/.claude)
  • Codex Config: ~/.codex (mapped from host ~/.codex)
  • Gemini Config: ~/.gemini (mapped from host ~/.gemini)
  • Project Files: Current directory mounted at /home/ai/code
  • Git Global Ignore: ~/.gitignore_global (mounted read-only from host)
  • SSH Keys: ~/.ssh (mounted read-only from host)
  • ccstatusline Config: ~/.config/ccstatusline (mounted read-only from host)

Note: All AI CLI configurations are directly mapped from your host machine, so changes persist automatically and are immediately available to the host system.

Container Naming

Containers are named based on the account and project directory:

  • Format: aibox-{AI_ACCOUNT}-{PROJECT_HASH}
  • Examples: aibox-default-a1b2c3d4, aibox-work-e5f6g7h8

The project hash is an 8-character MD5 hash of the project directory path. This allows:

  • Multiple projects: Each project gets its own container, even with the same account
  • Multiple terminals: All terminals in the same project share the same container
  • No conflicts: Running aibox in different projects won't close existing sessions

You can still switch between Claude, Codex, and Gemini within the same container.

Troubleshooting

Container Management

# Clean orphan containers before running
aibox --clean

# List all aibox containers
docker ps -a --filter "name=aibox"

# Attach to existing container
aibox --attach

# Force temporary container (auto-removed on exit)
aibox -r

Docker not installed

# Install Docker from https://docs.docker.com/get-docker/

Permission denied errors

# The container runs as ai user (UID 1001)
# If you still have issues, try removing the container:
docker rm -f aibox-default

# Then run again (it will pull fresh if needed):
aibox

Container won't start

# Clean orphan containers
aibox --clean

# Check Docker logs
docker logs aibox-default
docker logs aibox-work
docker logs aibox-personal

# Remove the container and let it be recreated
docker rm -f aibox-default
docker-compose down
aibox

# Check for updates and pull latest image if needed
aibox --update
# Or manually pull
docker pull ghcr.io/zzev/aibox:latest

Git operations failing

# Ensure SSH keys are mounted correctly
ls -la ~/.ssh  # Check host keys exist

# In container, verify keys are accessible
aibox
ls -la /home/ai/.ssh

# The container automatically handles macOS SSH config issues
# Git will use the cleaned config via the SSH wrapper
git pull  # Should work without UseKeychain errors

SSH "UseKeychain" errors (Automatically Fixed)

If you're on macOS, your SSH config likely contains UseKeychain options that aren't compatible with Linux. This is automatically handled by the container:

  • The entrypoint creates a cleaned SSH config without macOS-specific options
  • Git operations use a custom SSH wrapper that bypasses these issues
  • You don't need to modify your host SSH config

Git commits showing wrong author

The container automatically configures git with your environment variables on startup. If commits still show the wrong author:

# Check your profile file has the correct values
cat ~/.aibox/profiles/default.toml | grep -A 4 '\[git\]'

# Inside the container, verify git configuration
aibox
git config --global user.name
git config --global user.email

# Manually reconfigure if needed
git config --global user.name "Your Name"
git config --global user.email "your.email@example.com"

# Git is automatically configured on container startup via the entrypoint script

Note: The entrypoint script automatically sets git configuration from environment variables when the container starts.

Advanced Usage

Customizing Container User and Working Directory

The container uses predefined user settings (ai:1001:1001). The image is pre-built and hosted on GitHub Container Registry, so custom builds are not typically needed.

Custom Docker Image

You can configure a custom Docker image in your profile if you've built your own version:

Edit ~/.aibox/profiles/{account}.toml:

[docker]
image = "your-registry.com/your-image:tag"

By default, aibox uses ghcr.io/zzev/aibox:latest from the GitHub Container Registry.

Custom Docker Socket (Docker-in-Docker)

If AI CLIs need to interact with Docker:

  1. Uncomment in docker-compose.yml:
- /var/run/docker.sock:/var/run/docker.sock:ro
  1. The container user would need to be added to the docker group at build time (not recommended for security)

Custom Resource Limits

Edit docker-compose.yml:

deploy:
  resources:
    limits:
      cpus: "4" # Increase CPU limit
      memory: 8G # Increase memory limit

Using with CI/CD

# Non-interactive mode with auto-remove
aibox -r -a ci -t claude analyze src/
aibox -r -a ci -t codex

Best Practices

  1. Use accounts: Separate work/personal/client projects
  2. Choose the right CLI: Use -t flag to select between claude, codex, or gemini
  3. Regular updates: Check for updates with aibox --update or manually pull with docker pull ghcr.io/zzev/aibox:latest
  4. Profile management: Use aibox -p ACCOUNT_NAME to configure profiles
  5. Monitor resources: Check Docker stats for resource usage
  6. Container management: Uses docker-compose for simplified container lifecycle
  7. SSH compatibility: macOS SSH configs are automatically cleaned for Linux compatibility
  8. Configuration persistence: All CLI configs are mapped from host, changes persist automatically
# Check container status
docker ps -a --filter "name=aibox"

# Monitor resource usage
docker stats aibox-default
docker stats aibox-work
docker stats aibox-personal

# Clean orphans before running
aibox --clean

Limitations

  • No GUI applications support
  • Limited to mounted directories (can't access entire host filesystem)
  • Some system-level operations may not work
  • Docker-in-Docker requires additional configuration

Support

For issues or questions:

  1. Check the troubleshooting section above
  2. Review Docker logs: docker logs <container-name>
  3. Ensure all files are properly configured
  4. Verify Docker and Docker Compose are up to date

License

This Docker setup is provided as-is for use with AI CLIs. Ensure you comply with the respective terms of service when using Claude Code, Codex, or Gemini CLI.