Skip to content

Add Docker support for Windows and cross-platform execution#173

Open
Kenearos wants to merge 2 commits intofrankbria:mainfrom
Kenearos:claude/windows-compatibility-EwHYT
Open

Add Docker support for Windows and cross-platform execution#173
Kenearos wants to merge 2 commits intofrankbria:mainfrom
Kenearos:claude/windows-compatibility-EwHYT

Conversation

@Kenearos
Copy link

@Kenearos Kenearos commented Feb 10, 2026

Summary

This PR adds comprehensive Docker support to Ralph, enabling Windows users and anyone preferring containerized execution to run Ralph with full functionality. The implementation includes a production-ready Dockerfile, convenience wrapper scripts, Docker Compose configuration, and extensive documentation.

Key Changes

  • Dockerfile: Debian bookworm-slim image with all Ralph dependencies (bash, jq, git, tmux, Node.js 20 LTS, Claude Code CLI). Includes UID/GID remapping support via RALPH_UID and RALPH_GID environment variables to handle file permission issues on bind mounts.

  • Docker Entrypoint (docker/docker-entrypoint.sh): Handles runtime UID/GID remapping, git safe.directory configuration for mounted workspaces, and API key validation warnings.

  • Convenience Wrapper Scripts:

    • docker/ralph-docker (bash): Automatically handles volume mounts, UID/GID mapping, git config/SSH key mounting, and API key forwarding
    • docker/ralph-docker.ps1 (PowerShell): Windows-native wrapper with equivalent functionality
  • Docker Compose (docker-compose.yml): Simplified configuration for running Ralph with optional git integration mounts.

  • CI/CD Integration (.github/workflows/docker.yml): Automated workflow that builds the Docker image, verifies Ralph installation, checks all dependencies, and runs the test suite inside the container.

  • Build Configuration:

    • .dockerignore: Excludes Ralph state files, node_modules, coverage, and IDE files from the build context
    • .gitattributes: Forces LF line endings for shell scripts to prevent Windows CRLF corruption
  • Documentation (docs/user-guide/04-docker-setup.md): Comprehensive guide covering quick start, Docker Compose usage, file permissions, git integration, testing, Windows-specific considerations (line endings, volume mount performance, PowerShell environment variables), and troubleshooting.

  • README Updates: Added Docker Setup section with quick start examples for bash and PowerShell, plus reference to full documentation.

  • CLAUDE.md Updates: Documented Docker support, file purposes, and CI workflow integration.

Notable Implementation Details

  • The entrypoint uses gosu for proper signal handling and user switching instead of su
  • UID/GID remapping is optional (defaults to 1000:1000) but automatically set by wrapper scripts to match the host user
  • Git configuration is mounted read-only to prevent accidental modifications
  • The wrapper scripts intelligently mount git config and SSH keys only if they exist on the host
  • Windows PowerShell script uses backticks for line continuation and $env: for environment variables
  • .gitattributes ensures shell scripts maintain LF line endings even when cloned on Windows

https://claude.ai/code/session_01SNzxUdH1Udf26rN3RKNNzu

Summary by CodeRabbit

  • New Features

    • Docker containerization support for Ralph
    • Docker Compose service for simplified local development
    • Convenience wrapper scripts for Windows and Unix to run Ralph in Docker
  • Documentation

    • Comprehensive Docker setup guide and README updates for cross-platform usage
  • CI/CD

    • GitHub Actions workflow to build and test the Docker image
  • Maintenance

    • Added ignore/attributes files to improve Docker builds and cross-platform consistency

Enables Ralph to run inside a Docker container for Windows users
(via Docker Desktop) and anyone preferring containerized execution.

New files:
- Dockerfile (Debian slim + Node.js 20 + all Ralph dependencies)
- docker-compose.yml for easy startup
- docker/docker-entrypoint.sh with UID/GID remapping
- docker/ralph-docker (bash wrapper) and ralph-docker.ps1 (PowerShell)
- .gitattributes to prevent Windows CRLF line ending corruption
- .dockerignore for clean build context
- .github/workflows/docker.yml CI workflow
- docs/user-guide/04-docker-setup.md comprehensive documentation

Updated: README.md, CLAUDE.md, docs/user-guide/README.md, .gitignore

https://claude.ai/code/session_01SNzxUdH1Udf26rN3RKNNzu
@coderabbitai
Copy link
Contributor

coderabbitai bot commented Feb 10, 2026

Walkthrough

Adds Docker support: image build (Dockerfile), compose service, entrypoint with UID/GID remapping, shell and PowerShell wrappers, .dockerignore/.gitattributes, CI workflow for Docker builds/tests, and comprehensive docs and README/CLAUDE updates.

Changes

Cohort / File(s) Summary
Docker image & compose
Dockerfile, docker-compose.yml
New Dockerfile building Debian-based image with Node.js and Ralph CLI, non-root ralph user, and entrypoint; docker-compose service ralph with mounts, env vars, and default command.
Entrypoint & wrappers
docker/docker-entrypoint.sh, docker/ralph-docker, docker/ralph-docker.ps1
Adds entrypoint that remaps UID/GID, configures git safe.directory, warns on missing ANTHROPIC_API_KEY, and executes command as ralph; Bash and PowerShell wrapper scripts to run the image with optional git/SSH mounts.
CI workflow
.github/workflows/docker.yml
New GitHub Actions workflow to build the Docker image, run a container to verify CLI and runtime deps, and execute npm tests inside the container; triggers restricted to Docker-related paths on main/develop and PRs to main.
Git / repo metadata
.dockerignore, .gitattributes, .gitignore
Adds .dockerignore to exclude common runtime artifacts and Ralph internals from build context; enforces LF for shell/Docker files via .gitattributes; adds docker/tmp/ to .gitignore.
Docs & guides
README.md, CLAUDE.md, docs/user-guide/04-docker-setup.md, docs/user-guide/README.md
Adds Docker setup and usage docs, README instructions and examples, CLAUDE.md Docker section, and a detailed user-guide covering quick start, Windows notes, UID/GID mapping, testing, and troubleshooting.

Sequence Diagram(s)

mermaid
sequenceDiagram
actor Host
participant Wrapper as "docker/ralph-docker\n(docker run)"
participant Docker as "Docker Engine"
participant Container as "ralph container\n(/usr/local/bin/docker-entrypoint.sh)"
participant Ralph as "ralph CLI\n(/opt/ralph-claude-code)"
Host->>Wrapper: invoke wrapper (args, ANTHROPIC_API_KEY)
Wrapper->>Docker: docker run (env, volumes, image, cmd)
Docker->>Container: start container
Container->>Container: remap UID/GID, chown /workspace, set git safe.directory
Container->>Ralph: exec command as ralph user
Ralph->>Container: run CLI actions (tests, commands)
Container->>Host: exit status / logs

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Poem

🐰 I hopped into a Docker bay,
Built a box where Ralph can play,
UID dances, volumes sing,
API keys give the spring,
Container carrots—code hooray! 🥕🚢

🚥 Pre-merge checks | ✅ 3
✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title 'Add Docker support for Windows and cross-platform execution' directly and clearly describes the main objective of the PR, which is to introduce Docker support enabling Windows and containerized usage.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment

No actionable comments were generated in the recent review. 🎉

🧹 Recent nitpick comments
docs/user-guide/04-docker-setup.md (2)

141-147: Add language specification to code block.

The code block showing file paths should have a language identifier for better markdown rendering. Since these are example paths rather than executable code, consider using text or plaintext.

📝 Suggested fix
-```
+```text
 # Faster (WSL filesystem)
 \\wsl$\Ubuntu\home\user\my-project

161-163: Consider rephrasing for better readability.

Three consecutive sentences begin with "On", which affects readability. Consider consolidating or varying the sentence structure.

✍️ Suggested rephrase
-Docker Desktop is not started. On Windows, launch Docker Desktop from the Start menu and wait until the whale icon in the system tray shows "Docker Desktop is running". On macOS, launch it from Applications. On Linux, start the daemon with `sudo systemctl start docker`.
+Docker Desktop is not started. Launch Docker Desktop from the Start menu (Windows) or Applications (macOS) and wait until the whale icon shows "Docker Desktop is running". On Linux, start the daemon with `sudo systemctl start docker`.

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@macroscopeapp
Copy link
Contributor

macroscopeapp bot commented Feb 10, 2026

Add Docker-based build, entrypoint, and CI to run Ralph on Windows and other platforms via Dockerfile, docker-compose.yml, and GitHub Actions

Introduce a Debian-based Dockerfile with a docker-entrypoint.sh that remaps UID/GID and runs commands as user ralph, add docker-compose.yml, provide Bash/PowerShell wrapper scripts, and add a GitHub Actions workflow to build the image and run tests in-container. Update docs and ignores for Docker usage.

📍Where to Start

Start with the container behavior in docker/docker-entrypoint.sh, then review the image definition in Dockerfile and the CI workflow in .github/workflows/docker.yml.


Macroscope summarized b17b1a3.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 3

🤖 Fix all issues with AI agents
In @.github/workflows/docker.yml:
- Line 28: Update the GitHub Actions checkout step by replacing the uses
reference "actions/checkout@v3" with "actions/checkout@v4" to pick up Node.js
18+ compatibility; locate the workflow step that contains the literal uses:
actions/checkout@v3 and change it to actions/checkout@v4, then run a quick
actionlint or dry run to verify no other compatibility changes are required.

In `@docker/ralph-docker.ps1`:
- Around line 36-40: The script currently invokes Docker with "& docker
`@DockerArgs`" but does not propagate Docker's exit code; after the call capture
PowerShell's $LASTEXITCODE (or check $? then use $LASTEXITCODE) and call exit
with that value so non-zero Docker failures are returned to the caller; update
the section around the $RalphArgs/$DockerArgs handling and the "& docker
`@DockerArgs`" invocation to record $LASTEXITCODE and exit $LASTEXITCODE when
non-zero.

In `@Dockerfile`:
- Around line 16-19: Update the Node.js setup step in the Dockerfile to use
Node.js 24 LTS instead of 20 by replacing the nodesource setup script reference
"setup_20.x" with "setup_24.x" in the RUN command that installs Node.js; ensure
the rest of the command (apt-get install -y --no-install-recommends nodejs && rm
-rf /var/lib/apt/lists/*) remains unchanged so the image still installs nodejs
and cleans apt lists.
🧹 Nitpick comments (6)
.dockerignore (1)

1-34: Consider excluding directories unnecessary for the Docker build context.

.github/ and docs/ are likely not needed inside the image and would reduce build context size. Not blocking.

Suggested additions
 # IDE files
 .vscode/
 .idea/
 *.swp
 *.swo
+
+# CI and docs (not needed in image)
+.github/
+docs/
+docker/tmp/
docker/ralph-docker.ps1 (1)

28-34: Feature parity gap: no UID/GID or git config/SSH mounts.

The bash wrapper (docker/ralph-docker) reportedly supports RALPH_UID/RALPH_GID remapping and conditional git config / SSH key mounts. This PowerShell wrapper omits all of those. While Windows Docker Desktop handles permissions differently, passing RALPH_UID/RALPH_GID would still let the entrypoint do its remapping correctly for WSL2-backed containers.

Consider adding at minimum -e RALPH_UID / -e RALPH_GID for parity.

docker/ralph-docker (2)

38-45: Hardcoded ralph command limits wrapper to only ralph subcommands.

The wrapper always prepends ralph on Line 45, so users can't use it for other installed commands like ralph-monitor, ralph-enable, or arbitrary debugging (bash, etc.). Consider letting users pass the full command, or at minimum document this limitation.

♻️ Option: allow full command override
-    "$IMAGE_NAME" \
-    ralph "$@"
+    "$IMAGE_NAME" \
+    "$@"

Then usage becomes:

./docker/ralph-docker ralph --monitor
./docker/ralph-docker ralph-enable
./docker/ralph-docker bash   # debugging

If you prefer the current UX (implicit ralph prefix), add a note in the header comment that this wrapper is specifically for the ralph command.


1-16: Consider set -euo pipefail for stricter error handling.

set -e is present, but adding -u (unset variable errors) and -o pipefail (catch pipe failures) is a bash best practice for wrapper scripts that invoke docker run.

Dockerfile (1)

21-22: Pin @anthropic-ai/claude-code version for reproducible builds.

Without a version pin, npm install -g @anthropic-ai/claude-code`` will install whatever is latest at build time, making builds non-reproducible and potentially introducing breaking changes silently.

-RUN npm install -g `@anthropic-ai/claude-code`
+RUN npm install -g `@anthropic-ai/claude-code`@0.2.72

Replace 0.2.72 with the current version you've tested against.

docker/docker-entrypoint.sh (1)

9-13: Silent failure on UID/GID remapping could cause hard-to-debug permission issues.

If groupmod fails (e.g., the target GID is already used by another group), the || true swallows the error and ralph runs with an unexpected GID. Files created in /workspace would then have wrong ownership on the host.

Consider logging when remapping fails so users can diagnose permission problems:

♻️ Suggested improvement
 if [ "$(id -u ralph)" != "$RALPH_UID" ] || [ "$(id -g ralph)" != "$RALPH_GID" ]; then
-    groupmod -g "$RALPH_GID" ralph 2>/dev/null || true
-    usermod -u "$RALPH_UID" -g "$RALPH_GID" -d /home/ralph ralph 2>/dev/null || true
-    chown -R ralph:ralph /home/ralph 2>/dev/null || true
+    groupmod -g "$RALPH_GID" ralph 2>/dev/null || echo "WARNING: Could not remap ralph group to GID $RALPH_GID"
+    usermod -u "$RALPH_UID" -g "$RALPH_GID" -d /home/ralph ralph 2>/dev/null || echo "WARNING: Could not remap ralph user to UID $RALPH_UID"
+    chown -R ralph:ralph /home/ralph 2>/dev/null || true
 fi

runs-on: ubuntu-latest

steps:
- uses: actions/checkout@v3
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Update actions/checkout from v3 to v4.

As flagged by actionlint, actions/checkout@v3 uses Node.js 16 which is deprecated on GitHub Actions. Update to v4.

-    - uses: actions/checkout@v3
+    - uses: actions/checkout@v4
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
- uses: actions/checkout@v3
- uses: actions/checkout@v4
🧰 Tools
🪛 actionlint (1.7.10)

[error] 28-28: the runner of "actions/checkout@v3" action is too old to run on GitHub Actions. update the action's version to fix this issue

(action)

🤖 Prompt for AI Agents
In @.github/workflows/docker.yml at line 28, Update the GitHub Actions checkout
step by replacing the uses reference "actions/checkout@v3" with
"actions/checkout@v4" to pick up Node.js 18+ compatibility; locate the workflow
step that contains the literal uses: actions/checkout@v3 and change it to
actions/checkout@v4, then run a quick actionlint or dry run to verify no other
compatibility changes are required.

Comment on lines +36 to +40
if ($RalphArgs) {
$DockerArgs += $RalphArgs
}

& docker @DockerArgs
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Missing exit code propagation from docker run.

If docker run fails, the script exits with PowerShell's default exit code (0) rather than propagating Docker's non-zero exit code. This can mask failures in automation.

Proposed fix
 if ($RalphArgs) {
     $DockerArgs += $RalphArgs
 }
 
 & docker `@DockerArgs`
+$exitCode = $LASTEXITCODE
+if ($exitCode -ne 0) {
+    exit $exitCode
+}
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
if ($RalphArgs) {
$DockerArgs += $RalphArgs
}
& docker @DockerArgs
if ($RalphArgs) {
$DockerArgs += $RalphArgs
}
& docker `@DockerArgs`
$exitCode = $LASTEXITCODE
if ($exitCode -ne 0) {
exit $exitCode
}
🤖 Prompt for AI Agents
In `@docker/ralph-docker.ps1` around lines 36 - 40, The script currently invokes
Docker with "& docker `@DockerArgs`" but does not propagate Docker's exit code;
after the call capture PowerShell's $LASTEXITCODE (or check $? then use
$LASTEXITCODE) and call exit with that value so non-zero Docker failures are
returned to the caller; update the section around the $RalphArgs/$DockerArgs
handling and the "& docker `@DockerArgs`" invocation to record $LASTEXITCODE and
exit $LASTEXITCODE when non-zero.

Comment on lines +16 to +19
# Install Node.js 20 LTS
RUN curl -fsSL https://deb.nodesource.com/setup_20.x | bash - \
&& apt-get install -y --no-install-recommends nodejs \
&& rm -rf /var/lib/apt/lists/*
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

🧩 Analysis chain

🌐 Web query:

Node.js 20 end of life date EOL 2026

💡 Result:

Node.js 20.x (Iron) reaches End-of-Life (EOL) on April 30, 2026—after that date, the Node.js project ends official maintenance/security support for the 20.x line. [1][2]


🌐 Web query:

Node.js LTS schedule 22 24 support timeline 2026

💡 Result:

Node.js LTS support timeline (v22 vs v24) in/around 2026

Node.js 22.x (“Jod”)

  • Active LTS started: 2024-10-29
  • Maintenance LTS started: 2025-10-21 (so throughout all of 2026, v22 is in Maintenance LTS)
  • End-of-life (EOL): 2027-04-30 (security fixes stop) [2]
  • Current status shown on the official releases page: Maintenance LTS [1]

Node.js 24.x (“Krypton”)

  • Active LTS started: 2025-10-28 (so throughout most of 2026, v24 is in Active LTS)
  • Maintenance LTS starts: 2026-10-20 (switches from Active → Maintenance during 2026)
  • End-of-life (EOL): 2028-04-30 [2]
  • Current status shown on the official releases page: Active LTS [1]

Practical takeaway for 2026:

  • If you want the “most supported” LTS line during 2026, v24 is the primary choice (Active LTS until Oct 20, 2026).
  • v22 remains supported in 2026, but only in Maintenance LTS (security/backports, reduced feature/bugfix scope) until Apr 30, 2027. [2]

Sources: official Node.js releases page [1] and the Node.js Release Working Group schedule [2].


Upgrade to Node.js 24 LTS instead — Node.js 20 reaches end-of-life April 30, 2026.

Node.js 20 maintenance support ends April 30, 2026. Node.js 22 is currently in Maintenance LTS. For better long-term support, use Node.js 24, which is the current Active LTS and will remain supported through October 2026.

-RUN curl -fsSL https://deb.nodesource.com/setup_20.x | bash - \
+RUN curl -fsSL https://deb.nodesource.com/setup_24.x | bash - \
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
# Install Node.js 20 LTS
RUN curl -fsSL https://deb.nodesource.com/setup_20.x | bash - \
&& apt-get install -y --no-install-recommends nodejs \
&& rm -rf /var/lib/apt/lists/*
# Install Node.js 20 LTS
RUN curl -fsSL https://deb.nodesource.com/setup_24.x | bash - \
&& apt-get install -y --no-install-recommends nodejs \
&& rm -rf /var/lib/apt/lists/*
🤖 Prompt for AI Agents
In `@Dockerfile` around lines 16 - 19, Update the Node.js setup step in the
Dockerfile to use Node.js 24 LTS instead of 20 by replacing the nodesource setup
script reference "setup_20.x" with "setup_24.x" in the RUN command that installs
Node.js; ensure the rest of the command (apt-get install -y
--no-install-recommends nodejs && rm -rf /var/lib/apt/lists/*) remains unchanged
so the image still installs nodejs and cleans apt lists.

Add prerequisite note that Docker Desktop must be running, and add
troubleshooting entry for the most common Windows error with
platform-specific instructions to start the Docker daemon.

https://claude.ai/code/session_01SNzxUdH1Udf26rN3RKNNzu
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants