Skip to content

Repository files navigation

AI CLI in Docker

Run AI CLI tools (OpenAI Codex, Google Antigravity, Claude, OpenCode) inside Docker to keep your host clean while persisting CLI auth and config on your machine.

Contents

  • Why AI CLI in Docker?: Rationale behind this project.
  • Dockerfile.codex: Based on ghcr.io/openai/codex-universal with @openai/codex preinstalled. Automatically resumes the last session (codex resume --last), falling back to a new session if none exists.
  • Dockerfile.antigravity: Based on ubuntu:24.04 with the Google Antigravity CLI preinstalled.
  • Dockerfile.claude: Based on ubuntu:24.04 with @anthropic-ai/claude-code preinstalled. Supports launching in three variants with automatic fallback to starting a new session if no prior conversation exists: Standard Mode (πŸ’¬ with claude --continue || claude), Auto Mode (πŸ€– with claude --permission-mode auto --continue || claude --permission-mode auto), and Dangerous Mode (πŸ’€ with claude --dangerously-skip-permissions --continue || claude --dangerously-skip-permissions using a targeted LD_PRELOAD root privilege bypass).
  • Dockerfile.opencode: Based on ubuntu:24.04 with opencode-ai preinstalled.
  • activate.sh: Bash/Zsh helper functions.
  • ai-docker.sh: Interactive Bash TUI.
  • activate.ps1: PowerShell helper functions for Windows.
  • ai-docker.ps1: Interactive PowerShell menu for Windows.

Prerequisites

  • Docker installed and running.
  • One of:
    • Bash or Zsh (Linux/macOS).
    • PowerShell 5.1+ or PowerShell 7+ (Windows).

Quick Start (Bash/Zsh)

  1. Clone this repo and enter the directory.

  2. Source the activation script:

source ./activate.sh
  1. Launch the interactive TUI:
ai-docker
  1. Or run helpers directly:
  • claude-docker-shell
  • antigravity-docker-shell
  • codex-docker-shell
  • opencode-docker-shell

Quick Start (Windows PowerShell)

  1. Clone this repo and enter the directory in PowerShell.

  2. Load helper functions into your current session:

. .\activate.ps1

If script execution is blocked, run this first in the same terminal:

Set-ExecutionPolicy -Scope Process -ExecutionPolicy Bypass
  1. Launch the interactive menu:
ai-docker
  1. Or run helpers directly:
  • claude-docker-shell
  • antigravity-docker-shell
  • codex-docker-shell
  • opencode-docker-shell

Available helper commands

  • ai-docker: Launch interactive menu (Bash TUI or PowerShell menu).
  • codex-docker-build / codex-docker-shell
  • antigravity-docker-build / antigravity-docker-shell
  • claude-docker-build / claude-docker-shell
  • opencode-docker-build / opencode-docker-shell
  • docker-ai-build-all: Build all images with no cache.
  • codex-auth-docker-run: Run Codex auth flow inside container.
  • ai-docker-deactivate: Remove helper functions from current shell.

What you get when the container starts

  • A tmux session named after your current folder (overridable with TMUX_SESSION).
  • Windows:
    1. AI CLI (active by default): runs codex (resumes last session via codex resume --last), agy (Antigravity), claude, or opencode, then keeps shell open.
    2. Shell
    3. Shell
    4. htop

tmux basics in this setup

  • Switch windows:
    • Ctrl-b then n (next) / p (previous)
    • Ctrl-b then 1/2/3/4 to jump directly
    • Ctrl-b then w to choose from a list
  • Create a new window: Ctrl-b then c
  • Rename current window: Ctrl-b then ,
  • Close current window: type exit, or Ctrl-b then &
  • Detach from tmux: Ctrl-b then d
  • Re-attach inside container: tmux attach
  • Extra binding: Ctrl-b then Q prompts then kills all tmux sessions.

More tmux docs:

Make more room for the session name in tmux status bar

By default, tmux truncates the left status text. This setup increases the default status-left length to 60 characters and displays the active profile alongside the session name (e.g. workspace (default)).

  • One-off run: TMUX_STATUS_LEFT_LENGTH=80 antigravity-docker-shell
  • Persist for current shell session: export TMUX_STATUS_LEFT_LENGTH=80

Persist activation in shell profile

Add activation to your shell profile so helpers are available in new terminals.

Bash (~/.bashrc or ~/.bash_profile):

if [ -f "/absolute/path/to/ai-cli-in-docker/activate.sh" ]; then
  . "/absolute/path/to/ai-cli-in-docker/activate.sh"
fi

Zsh (~/.zshrc):

if [ -f "/absolute/path/to/ai-cli-in-docker/activate.sh" ]; then
  source "/absolute/path/to/ai-cli-in-docker/activate.sh"
fi

PowerShell ($PROFILE):

if (!(Test-Path $PROFILE)) { New-Item -ItemType File -Path $PROFILE -Force | Out-Null }
Add-Content -Path $PROFILE -Value '. "C:\absolute\path\to\ai-cli-in-docker\activate.ps1"'

Reload profile:

  • Bash: source ~/.bashrc
  • Zsh: source ~/.zshrc
  • PowerShell: . $PROFILE

Profiles and Configuration Storage

The CLI supports multiple isolated profiles. Only default is pre-defined, but you can create additional profiles (e.g., personal, work). Each profile isolates auth, configs, recent workspace paths, and environment files under: ~/.ai-docker-profiles/<profile-name>/

Specifically, for the active profile:

  • Codex:

    • Host: ~/.ai-docker-profiles/<profile>/codex-docker-config
    • Container: /root/.codex
  • Antigravity:

    • Host: ~/.ai-docker-profiles/<profile>/antigravity-cli-docker-config
    • Container: /root/.gemini
  • Claude:

    • Host: ~/.ai-docker-profiles/<profile>/claude-docker-config
    • Container: /root/.claude
    • /root/.claude.json is symlinked to /root/.claude/claude.json
  • OpenCode:

    • Host: ~/.ai-docker-profiles/<profile>/opencode-docker/local -> Container: /root/.local
    • Host: ~/.ai-docker-profiles/<profile>/opencode-docker/config -> Container: /root/.config/opencode
    • Host: ~/.ai-docker-profiles/<profile>/opencode-docker/docker-env.env -> Container environment variables
  • Git Configuration Sync: On shell launch, host Git configuration files (~/.gitconfig and ~/.config/git/config) are automatically copied into the active profile's directory mount and symlinked inside the container (/root/.gitconfig and /root/.config/git/config). This ensures your Git user identity, aliases, and settings are seamlessly available inside containers without single-file volume mount breakage on macOS VirtioFS.

Each host config directory includes a docker-env.env file that is passed to the container.

Managing Profiles and Recent Workspaces

  • Recent Projects Menu: Select πŸ•’ Recent Projects... on the main screen to view previously worked projects, their profile mappings, and instantly switch ("chdir") the active workspace.
  • Configurable History Limit: By default, recents history retains up to 30 unique projects. You can customize this by setting export AI_DOCKER_MAX_RECENTS=50 (or $env:AI_DOCKER_MAX_RECENTS=50 in PowerShell).
  • Switching Profiles via TUI: Select πŸ‘€ Switch Active Profile on the main screen to change profiles or create a new one.
  • Environment Override: Set the AI_DOCKER_PROFILE environment variable in your terminal session to override the active profile:
    export AI_DOCKER_PROFILE=work
  • Active Profile File: If AI_DOCKER_PROFILE is not set, the active profile defaults to the name stored in ~/.ai-docker-active-profile, and falls back to default if the file doesn't exist.

Selective Project-Based SSH Agent Socket Forwarding

Containers can selectively use your host's SSH agent on a per-project basis:

  • TUI Toggle: On the main ai-docker menu, select πŸ”‘ Project SSH Agent: [ Enabled | Disabled ] to toggle SSH agent socket forwarding for the currently active workspace.
  • Security First: Disabled by default (ssh_mount:0) for every project to maintain strong container isolation.
  • How It Works: When enabled (ssh_mount:1), the container bind-mounts the host's SSH agent socket (e.g. /run/host-services/ssh-auth.sock on macOS / Docker Desktop or $SSH_AUTH_SOCK on Linux) and exports SSH_AUTH_SOCK. Your private SSH key files stay safely in host memory/Keychain and are never copied into the container.
  • Settings Storage: Project settings are stored in ~/.ai-docker-profiles/project-ssh-settings in tag format (e.g. /path/to/project:ssh_mount:1).
  • Environment Override: Set export AI_DOCKER_ENABLE_SSH_AGENT=1 (or 0) in your shell to explicitly override SSH agent forwarding across sessions.

Passing environment variables

Add environment variables to the tool's docker-env.env file.

Example for Claude (~/.ai-docker-profiles/<profile>/claude-docker-config/docker-env.env):

ANTHROPIC_BASE_URL=http://host.docker.internal:1234
ANTHROPIC_AUTH_TOKEN=lm
ANTHROPIC_MODEL=mlx-community/qwen3.5-9b

Note: The container is pre-configured to export CLAUDE_CODE_RETRY_WATCHDOG=1 and CLAUDE_CODE_MAX_RETRIES=9999 for all Claude Code variants.

Known quirk with Codex auth link

codex-auth-docker-run may print a wrapped sign-in URL. If your terminal cannot open it directly:

  • Copy the full URL carefully.
  • Remove line breaks/spaces in a text editor.
  • Open the cleaned URL in your browser.

Running Tests

The project includes a comprehensive automated test suite. You can run it locally or let GitHub Actions run it in CI/CD.

Local Verification

You can execute the test suite locally using Docker. The host machine does not need Python, Pester, or other test tooling installed.

  • On macOS/Linux:
    chmod +x run-tests.sh
    ./run-tests.sh
  • On Windows (PowerShell):
    .\run-tests.ps1

Note: The PowerShell Pester test block is automatically skipped when running on ARM64/aarch64 hosts (such as Apple Silicon Mac machines) to prevent Docker/qemu architecture emulation issues.

CI/CD Pipeline

On every push or pull request to the main or master branches, GitHub Actions automatically triggers the Test Suite workflow. This workflow:

  1. Runs Python-based Bash helper and TUI navigation tests.
  2. Runs PowerShell Pester helper tests.
  3. Builds and verifies all four AI CLI images (claude, antigravity, codex, opencode) in parallel.

Tips and Tricks

How do I insert line breaks in messages?

Use Ctrl+J to insert a line break.

Verified in:

  • antigravity cli (agy)
  • codex cli
  • opencode

Additional tips

  • Rebuild after changing a Dockerfile: codex-docker-build, antigravity-docker-build, etc.
  • Remove helper functions from current shell: ai-docker-deactivate

Notes

  • On Linux hosts, codex-auth-docker-run uses --network=host by default.
  • On Windows/macOS with Docker Desktop, host networking is disabled by default in activate.ps1.
  • To force host networking in PowerShell helpers (only if your Docker setup supports it), set AI_DOCKER_USE_HOST_NETWORK=1.

About

Collection of AI CLI wrappers: Run AI CLI tools (OpenAI Codex, Google Gemini, OpenCode, Claude Code) inside Docker to keep your host clean while persisting CLI auth/config on your machine.

Topics

Resources

Stars

2 stars

Watchers

1 watching

Forks

Releases

Packages

Contributors

Languages