feat: add Docker isolation mode for safer YOLO execution#26
Merged
johannesjo merged 6 commits intomainfrom Mar 20, 2026
Merged
Conversation
When Docker is available, tasks can opt into running inside a container. Only the project directory is bind-mounted (read-write), so agents cannot accidentally delete or modify files outside the project. - spawnAgent() wraps command in `docker run` when dockerMode is set - Mounts ~/.ssh and ~/.gitconfig read-only for git operations - Forwards API keys and git identity env vars into container - NewTaskDialog shows "Run in Docker container" toggle when Docker detected - SettingsDialog allows configuring the default Docker image - Docker availability checked at app startup via `docker info` - Full persistence of dockerMode/dockerImage per task https://claude.ai/code/session_012QrKQQBc2hmjhPmkH2Fk6T
- Container lifecycle: named containers (--name), docker stop on kill, --label for identification, --network host, resource limits (8g/512 pids) - Env forwarding: switched from narrow allowlist to blocklist approach — all env vars forwarded except desktop/Electron/linker-specific ones - Credential mounts: added ~/.config/gh, ~/.npmrc, ~/.netrc, GOOGLE_APPLICATION_CREDENTIALS (all read-only) - UX: auto-enable Docker when skip-permissions toggled on, hint when YOLO without Docker, Docker unavailable suggestion, "Docker" badge on task headers, shell sessions inherit Docker mode from parent task https://claude.ai/code/session_012QrKQQBc2hmjhPmkH2Fk6T
- Add docker/Dockerfile with git, Node 20, Python 3, gh CLI, ripgrep, fd, fzf, build-essential, and other common dev tools pre-installed - Change default image from ubuntu:latest to parallel-code-agent:latest - Add IPC channels: CheckDockerImageExists, BuildDockerImage - Backend streams docker build output to renderer for progress display - NewTaskDialog shows image status, "Build Image" button when image not found locally, and build progress/output - Bundle Dockerfile in extraResources for production builds https://claude.ai/code/session_012QrKQQBc2hmjhPmkH2Fk6T
Dockerfile: - Replace curl|bash with proper apt keyring method for NodeSource - Upgrade to Node 22 LTS (Node 20 EOL April 2026) - Combine apt repo setup into single layer for cache efficiency - Add git-lfs, procps, less; remove cmake - Create non-root agent user (uid 1000) - Pin npm@10 instead of npm@latest Backend (pty.ts): - Fix __dirname undefined in ESM — add fileURLToPath polyfill - Block SSH_AUTH_SOCK, GPG_AGENT_INFO, KUBECONFIG, SUDO_* from leaking into containers - Use 12-char agentId prefix for container names (was 8) - Add --user flag to match host UID/GID - Use synchronous docker kill in killAllAgents to prevent orphans - Rename isDockerImageExists → dockerImageExists - Add build deduplication guard (activeBuild singleton) Frontend (NewTaskDialog.tsx): - Reset docker state signals on dialog reopen - Debounce image existence check (300ms) - Auto-scroll build output <pre> to bottom UI (TaskPanel.tsx): - Move Docker badge before task name (consistent with directMode badge) - Normalize badge padding/opacity to match directMode style https://claude.ai/code/session_012QrKQQBc2hmjhPmkH2Fk6T
Replace `containerName!` with a local `const name = containerName as string` inside the dockerMode guard where the value is guaranteed non-null. https://claude.ai/code/session_012QrKQQBc2hmjhPmkH2Fk6T
…, plan watcher leak, docker defaults, notifications, async docker checks 1. Add missing check_docker_image_exists and build_docker_image to preload allowlist — these IPC calls were silently blocked at runtime. 2. Restore SpawnAgent input validation for command, args, taskId, agentId, cols, rows, dockerMode, and dockerImage. 3. Restore UUID suffix in branch names to prevent collisions when two tasks share the same name. 4. Add StopPlanWatcher IPC channel and call it from collapseTask/closeTask to prevent FSWatcher accumulation for closed/collapsed tasks. 5. Fix docker image default inconsistency: persistence.ts and SettingsDialog.tsx now use 'parallel-code-agent:latest' consistently instead of 'ubuntu:latest'. 6. Add Notification.isSupported() guard and 30-second Linux timeout fallback to ShowNotification handler. 7. Replace execFileSync with async execFile in isDockerAvailable and dockerImageExists to avoid blocking the Electron main thread. https://claude.ai/code/session_012QrKQQBc2hmjhPmkH2Fk6T
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
When Docker is available, tasks can opt into running inside a container.
Only the project directory is bind-mounted (read-write), so agents
cannot accidentally delete or modify files outside the project.
docker runwhen dockerMode is setdocker infohttps://claude.ai/code/session_012QrKQQBc2hmjhPmkH2Fk6T