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:
.env.local(if exists).env(if exists)- 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
~/.sshdirectory 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_cleanwithout macOS options - Git uses a custom SSH wrapper (
/tmp/ssh-wrapper) that uses the cleaned config - When
SSH_KEY_FILEis specified, Git is configured to use that specific key - The script warns if the specified key file doesn't exist
Security Features
- Non-root User: All CLIs run as
aiuser (UID 1001) without any sudo privileges - Capability Dropping: Container drops all Linux capabilities except essential ones
- No New Privileges: Prevents privilege escalation
- Read-only Mounts: SSH keys mounted as read-only (config is filtered, not modified)
- Network Isolation: Runs in isolated Docker network (
ai-network) with host access viahost.docker.internal - Resource Limits: CPU (2 cores max) and memory (4GB max) limits
- 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:
- Uncomment in
docker-compose.yml:
- /var/run/docker.sock:/var/run/docker.sock:ro
- 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
- Use accounts: Separate work/personal/client projects
- Choose the right CLI: Use
-tflag to select between claude, codex, or gemini - Regular updates: Check for updates with
aibox --updateor manually pull withdocker pull ghcr.io/zzev/aibox:latest - Profile management: Use
aibox -p ACCOUNT_NAMEto configure profiles - Monitor resources: Check Docker stats for resource usage
- Container management: Uses docker-compose for simplified container lifecycle
- SSH compatibility: macOS SSH configs are automatically cleaned for Linux compatibility
- 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:
- Check the troubleshooting section above
- Review Docker logs:
docker logs <container-name> - Ensure all files are properly configured
- 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.