An isolated, secure containerized development environment framework designed specifically for running autonomous coding agents on your local web applications. It supports multiple LLM CLI agents (Gemini, Claude, Mistral) via a pluggable, unified runner interface and shares a single global safety guidelines configuration.
Docker Desktop requires a paid subscription for commercial use in larger organizations (defined as more than 250 employees OR more than $10 million in annual revenue).
To run containerized development environments without requiring a paid subscription, developers can use free, open-source alternatives depending on their host operating system:
- macOS: Use Colima, a lightweight, open-source tool that runs a standard Docker Engine inside a macOS VM.
- Windows: Colima is not supported on Windows. Use WSL2 (Windows Subsystem for Linux) with a native Docker Engine installation.
- Linux: Colima is redundant on Linux. The Docker Engine runs natively on Linux free of charge.
This project is fully compatible with native Docker engines, WSL2 environments, and Colima setups out of the box.
The project is structured with a centralized runner at the root and one self-contained folder per vendor. Each vendor folder holds everything specific to that engine: its Docker build, its driver config for both runners, and its stream formatter. Adding a vendor means adding a folder β the runners discover engines by looking for agent.conf / agent.psd1.
/Users/localkevin/workspace/Agentic Docker Image/
βββ run-agent.sh # Central Bash runner script
βββ run-agent.ps1 # Central PowerShell runner script
βββ guidelines.txt # Global safety guidelines (appended to all prompts)
βββ prompt.txt / prompt.md # Shared prompt file (either is supported)
βββ README.md # This instructions file
βββ gemini/
β βββ Dockerfile # Gemini (Antigravity CLI) Docker build
β βββ agent.conf # Gemini driver config (Bash)
β βββ agent.psd1 # Gemini driver config (PowerShell)
β βββ stream-formatter.py # Gemini stream-json renderer
βββ mistral/
β βββ Dockerfile # Mistral (Vibe CLI) Docker build
β βββ agent.conf # Mistral driver config (Bash)
β βββ agent.psd1 # Mistral driver config (PowerShell)
βββ claude/
βββ Dockerfile # Claude (Claude Code CLI) Docker build
βββ agent.conf # Claude driver config (Bash)
βββ agent.psd1 # Claude driver config (PowerShell)
βββ stream-formatter.py # Claude stream-json renderer
A driver declares the CLI arguments for each invocation mode, so the runner holds no vendor-specific flag grammar:
| Key | Used when |
|---|---|
ARGS_COMMON / ArgsCommon |
Prepended in every mode |
ARGS_INTERACTIVE / ArgsInteractive |
No prompt β interactive TUI |
ARGS_TUI / ArgsTui |
Prompt delivered to the TUI (-t) |
ARGS_HEADLESS / ArgsHeadless |
Prompt, no stream formatter declared |
ARGS_STREAM / ArgsStream |
Prompt, output piped through STREAM_FORMATTER |
The standalone token {{PROMPT}} in any mode array is replaced with the final prompt text (prompt plus guidelines). A mode array without the token never receives a prompt. ENV_FILE / EnvFile optionally names a host env file to load before the auth check (a leading ~ is expanded in the PowerShell driver).
A driver also declares the container stdin flags for each mode, so the runner holds no assumptions about which modes need a terminal:
| Key | Used when | Typical value |
|---|---|---|
STDIN_INTERACTIVE / StdinInteractive |
No prompt β interactive TUI | -i -t |
STDIN_TUI / StdinTui |
Prompt delivered to the TUI (-t) |
-i -t |
STDIN_HEADLESS / StdinHeadless |
Prompt, no stream formatter | -i |
STDIN_STREAM / StdinStream |
Prompt, output piped through the formatter | -i |
The interactive modes need a PTY: these CLIs switch themselves to non-interactive print mode when stdin is not a terminal, so a container without -t never reaches its TUI. The streamed mode must not request one β its stdout is piped into the formatter and its stdin comes from /dev/null, and Docker refuses to allocate a TTY for a container whose stdin is not a terminal. A mode left undeclared falls back to -i alone.
-t/--tuionly chooses how a prompt is delivered. It selectsARGS_TUIover the headless or streamed mode, so it is a no-op unless a prompt is also supplied. To get a bare interactive session, pass no prompt at all βrun-agent.sh -c claude .
To ensure maximum security, Git is not installed on any of the Docker images.
This creates a strict security boundary:
- The agent running inside the container cannot access your host's global Git credentials or SSH keys.
- The agent cannot write unauthorized commits, modify Git history, or execute
git pushto your remote repositories. - You review all changes on your host machine using your local Git client before staging and pushing.
To prevent agents from being "too eager" to modify the workspace, the runner supports role-based workspace mounting:
- Coder Mode (
default): Mounts the workspace as read-write (rw). The agent is allowed to edit code, initialize files, and execute scripts. - Design/Spec Mode (
design/spec): Mounts the workspace as read-only (ro). This physical boundary guarantees that the container cannot modify any files. The runner automatically appends specific design and planning instructions to guide the agent.
All Docker images include the following pre-configured runtimes and developer tools:
- Node.js (v20.x) & npm (v10.x)
- TypeScript (v6.x) &
ts-node - Python (v3.11.x) &
pip - Global Linters & Formatters:
eslint,prettier - Bundlers:
webpack,webpack-cli - CLI Utilities:
curl,ca-certificates,wget,jq,ripgrep(rg), andbuild-essential.
To bypass PEP 668 restrictions ("externally-managed-environment") in modern Debian systems, a global virtual environment is pre-configured at /opt/venv and injected directly into the container's PATH. Any python packages installed by agents will automatically compile inside this environment safely.
The guidelines.txt file at the root of the project contains shared rules and safety boundaries. The runner script will automatically append the contents of guidelines.txt to the end of every prompt you run.
This is highly useful for defining permanent system instructions or safety rules for the agent.
The centralized runner supports the following options:
run-agent.sh [options] [workspace_path] [prompt_arguments]-c | --container | --engine <name>: The engine driver to load from the matching vendor folder (gemini,claude,mistral). Defaults togemini.-r | --role | --mode <role>: The execution role (coder,design,spec). Defaults tocoder.-p | --prompt <string>: Directly passes the prompt.-t | --tui: Delivers the prompt to the interactive TUI instead of running headless. No effect without a prompt.-v | --verbose: Appends the driver's verbose flag, when it declares one and the selected mode has not already.
Ensure Colima (or your local Docker daemon) is active on your host machine: colima start
- Command:
agy - Auth Modes:
- API Key: Export
GEMINI_API_KEY="your_key"on your host. - Google One OAuth: Unset
GEMINI_API_KEYon your host. Runs interactively to complete browser OAuth.
- API Key: Export
- Volume Persistence: Mounts named volume
agentic-coder-geminito/home/node/.geminito save settings and OAuth credentials.
- Command:
vibe - Auth Modes:
- API Key: Export
MISTRAL_API_KEY="your_key"on your host. - Interactive Setup: Unset
MISTRAL_API_KEYand run interactively to input your Mistral API key.
- API Key: Export
- Volume Persistence: Mounts named volume
agentic-coder-vibeto/home/node/.vibeto preserveconfig.toml.
- Command:
claude - Auth Modes:
- API Key: Export
ANTHROPIC_API_KEY="your_key"on your host. - Anthropic OAuth: Unset
ANTHROPIC_API_KEYand run interactively to copy-paste browser OAuth credentials.
- API Key: Export
- Volume Persistence: Mounts named volume
agentic-coder-claudeto/home/node/.claude, which holds the OAuth credentials (.credentials.json) and settings. - Known limitation β interactive mode re-prompts for folder trust. The CLI keeps its per-directory trust decision and onboarding flags in
~/.claude.json, which sits beside~/.clauderather than inside it, so that file is not persisted and the "Do you trust the files in this folder?" dialog appears on every interactive run. This is deliberate: the CLI is installed under~/.local/bin, so persisting the whole home directory would shadow the binary and a rebuilt image would keep running the old CLI. Disposable images are worth more than skipping one dialog. Prompted runs are unaffected β print mode skips the trust gate entirely.- In that dialog, trust the
β―cursor position rather than the highlight: on low-contrast themes the selected row can look greyed out, and confirming the default "No, exit" makes the CLI exit cleanly with code 1 and no error message.
- In that dialog, trust the
You can add these global aliases to your ~/.zshrc to launch the agents easily from anywhere on your Mac:
# Central Agent Runner
alias run-agent='"/Users/localkevin/workspace/Agentic Docker Image/run-agent.sh"'
# Quick Engine Launchers
alias agy-run='run-agent -c gemini'
alias vibe-run='run-agent -c mistral'
alias claude-run='run-agent -c claude'
# Read-Only Specification/Design Mode
alias spec-run='run-agent -r design'Reload your profile (source ~/.zshrc), then execute them like:
# Run Claude as a coder with a prompt
claude-run /path/to/web-app "Refactor buttons to typescript"
# Run Gemini in Read-Only Design Mode to draft code specs
spec-run -c gemini /path/to/web-app "Draft an architecture plan for task management"