feat(docker): add Docker-based Windows and cross-platform support

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
This commit is contained in:
Claude 2026-02-10 20:54:23 +00:00
parent 605e50f725
commit c01133bd8d
No known key found for this signature in database
13 changed files with 538 additions and 0 deletions

34
.dockerignore Normal file
View file

@ -0,0 +1,34 @@
# Git
.git
# Node modules
node_modules/
# Ralph state files (rebuilt at runtime)
.ralph/.call_count
.ralph/.last_reset
.ralph/.exit_signals
.ralph/.response_analysis
.ralph/.circuit_breaker_state
.ralph/.circuit_breaker_history
.ralph/.json_parse_result
.ralph/.last_output_length
.ralph/.ralph_session
.ralph/.ralph_session_history
.ralph/.claude_session_id
.ralph/status.json
.ralph/logs/
# Coverage and test artifacts
coverage/
*.log
# OS files
.DS_Store
Thumbs.db
# IDE files
.vscode/
.idea/
*.swp
*.swo

21
.gitattributes vendored Normal file
View file

@ -0,0 +1,21 @@
# Force LF line endings for all shell scripts and test files
# Prevents Windows CRLF corruption of bash scripts
*.sh text eol=lf
*.bats text eol=lf
*.bash text eol=lf
# Docker files
Dockerfile text eol=lf
docker-compose.yml text eol=lf
docker-entrypoint.sh text eol=lf
# Keep markdown and other text files as auto
*.md text
*.yml text
*.yaml text
*.json text
# Binary files
*.png binary
*.jpg binary
*.gif binary

51
.github/workflows/docker.yml vendored Normal file
View file

@ -0,0 +1,51 @@
name: Docker Build
on:
push:
branches: [ main, develop ]
paths:
- 'Dockerfile'
- 'docker/**'
- '.dockerignore'
- 'install.sh'
- 'lib/**'
- 'ralph_loop.sh'
pull_request:
branches: [ main ]
paths:
- 'Dockerfile'
- 'docker/**'
- '.dockerignore'
- 'install.sh'
- 'lib/**'
- 'ralph_loop.sh'
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Build Docker image
run: docker build -t ralph-claude-code:test .
- name: Verify Ralph is installed
run: docker run --rm ralph-claude-code:test ralph --help
- name: Verify dependencies
run: |
docker run --rm ralph-claude-code:test bash -c '
echo "=== Checking dependencies ==="
bash --version | head -1
node --version
npm --version
jq --version
git --version
tmux -V
timeout --version | head -1
echo "=== All dependencies OK ==="
'
- name: Run tests inside Docker
run: docker run --rm ralph-claude-code:test bash -c 'cd /opt/ralph-claude-code && npm test'

3
.gitignore vendored
View file

@ -45,6 +45,9 @@ target/
*.swp *.swp
*.swo *.swo
# Docker
docker/tmp/
# Claude Code local settings # Claude Code local settings
.claude/settings.local.json .claude/settings.local.json

View file

@ -330,6 +330,34 @@ After installation, the following global commands are available:
- `ralph-enable` - Interactive wizard to enable Ralph in existing projects - `ralph-enable` - Interactive wizard to enable Ralph in existing projects
- `ralph-enable-ci` - Non-interactive version for CI/automation - `ralph-enable-ci` - Non-interactive version for CI/automation
## Docker Support
Ralph can run inside a Docker container for Windows users or containerized workflows.
### Docker Files
- **`Dockerfile`** - Debian slim image with all Ralph dependencies (bash, jq, git, tmux, Node.js 20, Claude Code CLI)
- **`docker-compose.yml`** - Compose configuration with volume mounts and API key passthrough
- **`docker/docker-entrypoint.sh`** - Entrypoint handling UID/GID remapping and git safe.directory
- **`docker/ralph-docker`** - Bash convenience wrapper for `docker run`
- **`docker/ralph-docker.ps1`** - PowerShell convenience wrapper for Windows
- **`.dockerignore`** - Build context exclusions
- **`.gitattributes`** - Forces LF line endings for shell scripts (prevents Windows CRLF corruption)
### Docker Commands
```bash
# Build image
docker build -t ralph-claude-code .
# Run Ralph
docker run -it --rm -e ANTHROPIC_API_KEY="$KEY" -v "$(pwd):/workspace" ralph-claude-code ralph --monitor
# Run tests inside container
docker run --rm ralph-claude-code bash -c 'cd /opt/ralph-claude-code && npm test'
```
### CI Workflow
`.github/workflows/docker.yml` verifies the Docker image builds and all tests pass inside the container.
## Integration Points ## Integration Points
Ralph integrates with: Ralph integrates with:
@ -338,6 +366,7 @@ Ralph integrates with:
- **Git**: Expects projects to be git repositories - **Git**: Expects projects to be git repositories
- **jq**: For JSON processing of status and exit signals - **jq**: For JSON processing of status and exit signals
- **GitHub Actions**: CI/CD pipeline for automated testing - **GitHub Actions**: CI/CD pipeline for automated testing
- **Docker**: Container-based execution for Windows and cross-platform support
- **Standard Unix tools**: bash, grep, date, etc. - **Standard Unix tools**: bash, grep, date, etc.
## Exit Conditions and Thresholds ## Exit Conditions and Thresholds

46
Dockerfile Normal file
View file

@ -0,0 +1,46 @@
FROM debian:bookworm-slim
# System dependencies
RUN apt-get update && apt-get install -y --no-install-recommends \
bash \
jq \
git \
tmux \
coreutils \
curl \
ca-certificates \
gosu \
procps \
&& rm -rf /var/lib/apt/lists/*
# 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 Claude Code CLI globally
RUN npm install -g @anthropic-ai/claude-code
# Create ralph user
RUN groupadd -g 1000 ralph \
&& useradd -m -u 1000 -g ralph -s /bin/bash ralph
# Copy Ralph source
COPY . /opt/ralph-claude-code/
# Install Ralph as the ralph user
USER ralph
RUN cd /opt/ralph-claude-code && bash install.sh
ENV PATH="/home/ralph/.local/bin:${PATH}"
# Switch back to root for entrypoint (handles UID remapping)
USER root
# Copy entrypoint
COPY docker/docker-entrypoint.sh /usr/local/bin/
RUN chmod +x /usr/local/bin/docker-entrypoint.sh
WORKDIR /workspace
ENTRYPOINT ["docker-entrypoint.sh"]
CMD ["ralph", "--help"]

View file

@ -248,6 +248,36 @@ To completely remove Ralph from your system:
curl -sL https://raw.githubusercontent.com/frankbria/ralph-claude-code/main/uninstall.sh | bash curl -sL https://raw.githubusercontent.com/frankbria/ralph-claude-code/main/uninstall.sh | bash
``` ```
## Docker Setup (Windows & Cross-Platform)
Ralph can run inside a Docker container, which is the recommended approach for **Windows** users. It also works on Linux and macOS.
```bash
# 1. Build the image (one time)
docker build -t ralph-claude-code .
# 2. Run Ralph in your project
cd /path/to/your-project
docker run -it --rm \
-e ANTHROPIC_API_KEY="$ANTHROPIC_API_KEY" \
-v "$(pwd):/workspace" \
ralph-claude-code \
ralph --monitor
```
**Windows PowerShell:**
```powershell
docker run -it --rm `
-e ANTHROPIC_API_KEY="$env:ANTHROPIC_API_KEY" `
-v "${PWD}:/workspace" `
ralph-claude-code `
ralph --monitor
```
Convenience wrapper scripts are available in `docker/` (bash and PowerShell).
> See [Docker Setup Guide](docs/user-guide/04-docker-setup.md) for full documentation including Docker Compose, file permissions, git integration, and troubleshooting.
## Understanding Ralph Files ## Understanding Ralph Files
After running `ralph-enable` or `ralph-import`, you'll have a `.ralph/` directory with several files. Here's what each file does and whether you need to edit it: After running `ralph-enable` or `ralph-import`, you'll have a `.ralph/` directory with several files. Here's what each file does and whether you need to edit it:

21
docker-compose.yml Normal file
View file

@ -0,0 +1,21 @@
services:
ralph:
build:
context: .
dockerfile: Dockerfile
image: ralph-claude-code:latest
container_name: ralph
stdin_open: true
tty: true
working_dir: /workspace
environment:
- ANTHROPIC_API_KEY=${ANTHROPIC_API_KEY}
- RALPH_UID=${RALPH_UID:-1000}
- RALPH_GID=${RALPH_GID:-1000}
volumes:
- ./:/workspace
# Optional: mount git config for commits
# - ~/.gitconfig:/home/ralph/.gitconfig:ro
# Optional: mount SSH keys for git push
# - ~/.ssh:/home/ralph/.ssh:ro
command: ["ralph", "--help"]

View file

@ -0,0 +1,26 @@
#!/bin/bash
set -e
# Default UID/GID matching typical Linux/macOS user
RALPH_UID=${RALPH_UID:-1000}
RALPH_GID=${RALPH_GID:-1000}
# Remap ralph user UID/GID to match host user (avoids file permission issues on bind mounts)
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
fi
# Git safe.directory for mounted workspace
gosu ralph git config --global --add safe.directory /workspace 2>/dev/null || true
# Warn if API key is missing
if [ -z "$ANTHROPIC_API_KEY" ]; then
echo "WARNING: ANTHROPIC_API_KEY is not set. Ralph will not be able to call Claude."
echo "Set it with: docker run -e ANTHROPIC_API_KEY=your-key ..."
echo ""
fi
# Execute command as ralph user
exec gosu ralph "$@"

45
docker/ralph-docker Executable file
View file

@ -0,0 +1,45 @@
#!/bin/bash
# ralph-docker - Convenience wrapper for running Ralph in Docker
#
# Usage:
# ./docker/ralph-docker [ralph-options]
#
# Examples:
# ./docker/ralph-docker --help
# ./docker/ralph-docker --monitor
# ./docker/ralph-docker --live --verbose
#
# Environment:
# ANTHROPIC_API_KEY Required. Your Anthropic API key.
# RALPH_IMAGE Optional. Docker image name (default: ralph-claude-code:latest)
set -e
IMAGE_NAME="${RALPH_IMAGE:-ralph-claude-code:latest}"
if [ -z "$ANTHROPIC_API_KEY" ]; then
echo "Error: ANTHROPIC_API_KEY environment variable is not set."
echo "Export it first: export ANTHROPIC_API_KEY=sk-ant-..."
exit 1
fi
EXTRA_VOLUMES=()
# Mount git config if available
if [ -f "$HOME/.gitconfig" ]; then
EXTRA_VOLUMES+=(-v "$HOME/.gitconfig:/home/ralph/.gitconfig:ro")
fi
# Mount SSH keys if available
if [ -d "$HOME/.ssh" ]; then
EXTRA_VOLUMES+=(-v "$HOME/.ssh:/home/ralph/.ssh:ro")
fi
docker run -it --rm \
-e ANTHROPIC_API_KEY="$ANTHROPIC_API_KEY" \
-e RALPH_UID="$(id -u)" \
-e RALPH_GID="$(id -g)" \
-v "$(pwd):/workspace" \
"${EXTRA_VOLUMES[@]}" \
"$IMAGE_NAME" \
ralph "$@"

40
docker/ralph-docker.ps1 Normal file
View file

@ -0,0 +1,40 @@
# ralph-docker.ps1 - Convenience wrapper for running Ralph in Docker on Windows
#
# Usage:
# .\docker\ralph-docker.ps1 [ralph-options]
#
# Examples:
# .\docker\ralph-docker.ps1 --help
# .\docker\ralph-docker.ps1 --monitor
# .\docker\ralph-docker.ps1 --live --verbose
#
# Environment:
# ANTHROPIC_API_KEY Required. Your Anthropic API key.
# RALPH_IMAGE Optional. Docker image name (default: ralph-claude-code:latest)
param(
[Parameter(ValueFromRemainingArguments = $true)]
[string[]]$RalphArgs
)
$ImageName = if ($env:RALPH_IMAGE) { $env:RALPH_IMAGE } else { "ralph-claude-code:latest" }
if (-not $env:ANTHROPIC_API_KEY) {
Write-Error "ANTHROPIC_API_KEY environment variable is not set."
Write-Host 'Set it first: $env:ANTHROPIC_API_KEY = "sk-ant-..."'
exit 1
}
$DockerArgs = @(
"run", "-it", "--rm",
"-e", "ANTHROPIC_API_KEY=$env:ANTHROPIC_API_KEY",
"-v", "${PWD}:/workspace",
$ImageName,
"ralph"
)
if ($RalphArgs) {
$DockerArgs += $RalphArgs
}
& docker @DockerArgs

View file

@ -0,0 +1,189 @@
# Docker Setup (Windows & Cross-Platform)
Ralph runs natively on Linux and macOS. For **Windows** users (or anyone who prefers containerized execution), Ralph can run inside a Docker container with full functionality.
## Prerequisites
- [Docker Desktop](https://www.docker.com/products/docker-desktop/) (Windows/macOS) or Docker Engine (Linux)
- Windows users: Docker Desktop must use the **WSL 2 backend** (default on modern installations)
- Your `ANTHROPIC_API_KEY`
## Quick Start
### 1. Build the image
From the Ralph repository root:
```bash
docker build -t ralph-claude-code .
```
### 2. Run Ralph in your project
```bash
cd /path/to/your-project
docker run -it --rm \
-e ANTHROPIC_API_KEY="$ANTHROPIC_API_KEY" \
-v "$(pwd):/workspace" \
ralph-claude-code \
ralph --monitor
```
**Windows PowerShell:**
```powershell
cd C:\path\to\your-project
docker run -it --rm `
-e ANTHROPIC_API_KEY="$env:ANTHROPIC_API_KEY" `
-v "${PWD}:/workspace" `
ralph-claude-code `
ralph --monitor
```
## Using Docker Compose
The repository includes a `docker-compose.yml` for convenience:
```bash
# Set your API key
export ANTHROPIC_API_KEY="sk-ant-..."
# Run Ralph
docker compose run --rm ralph ralph --monitor
```
To customize, edit `docker-compose.yml`. Uncomment the volume mounts for git config and SSH keys if you need git push from inside the container:
```yaml
volumes:
- ./:/workspace
- ~/.gitconfig:/home/ralph/.gitconfig:ro
- ~/.ssh:/home/ralph/.ssh:ro
```
## Convenience Wrapper Scripts
The `docker/` directory contains wrapper scripts that handle volume mounts, UID mapping, and API key forwarding automatically:
**Linux/macOS/WSL:**
```bash
./docker/ralph-docker --monitor
./docker/ralph-docker --live --verbose
```
**Windows PowerShell:**
```powershell
.\docker\ralph-docker.ps1 --monitor
.\docker\ralph-docker.ps1 --live --verbose
```
## File Permissions (UID/GID Mapping)
When Docker mounts your project directory, files created inside the container need to have the correct ownership on the host. The container supports `RALPH_UID` and `RALPH_GID` environment variables:
```bash
docker run -it --rm \
-e ANTHROPIC_API_KEY="$ANTHROPIC_API_KEY" \
-e RALPH_UID="$(id -u)" \
-e RALPH_GID="$(id -g)" \
-v "$(pwd):/workspace" \
ralph-claude-code \
ralph --monitor
```
The wrapper scripts (`docker/ralph-docker`) set these automatically.
## Git Integration
To enable git commits and pushes from inside the container, mount your git configuration:
```bash
docker run -it --rm \
-e ANTHROPIC_API_KEY="$ANTHROPIC_API_KEY" \
-v "$(pwd):/workspace" \
-v "$HOME/.gitconfig:/home/ralph/.gitconfig:ro" \
-v "$HOME/.ssh:/home/ralph/.ssh:ro" \
ralph-claude-code \
ralph --monitor
```
## Running Tests Inside Docker
```bash
# Run all tests
docker run --rm ralph-claude-code bash -c 'cd /opt/ralph-claude-code && npm test'
# Run specific test suite
docker run --rm ralph-claude-code bash -c 'cd /opt/ralph-claude-code && npm run test:unit'
```
## Windows-Specific Notes
### Line Endings
The repository includes a `.gitattributes` file that forces LF line endings for all shell scripts. This prevents Windows' CRLF line endings from corrupting bash scripts. If you clone the repository on Windows, this is handled automatically.
If you encounter `\r` errors when running scripts, ensure `.gitattributes` is respected:
```bash
git config core.autocrlf input
git rm --cached -r .
git reset --hard
```
### Volume Mount Performance
For best performance on Windows, store your projects in the WSL 2 filesystem rather than the Windows filesystem:
```
# Faster (WSL filesystem)
\\wsl$\Ubuntu\home\user\my-project
# Slower (Windows filesystem mounted in WSL)
/mnt/c/Users/user/my-project
```
### PowerShell Environment Variables
```powershell
# Set API key for current session
$env:ANTHROPIC_API_KEY = "sk-ant-..."
# Or persist across sessions
[Environment]::SetEnvironmentVariable("ANTHROPIC_API_KEY", "sk-ant-...", "User")
```
## Troubleshooting
### "ANTHROPIC_API_KEY is not set"
The container warns if no API key is provided. Pass it with `-e ANTHROPIC_API_KEY=...`.
### Permission denied on mounted files
Set `RALPH_UID` and `RALPH_GID` to match your host user (see File Permissions section above).
### tmux not working
Ensure you run the container with `-it` flags (interactive + TTY). Without TTY, tmux cannot create sessions. Use `ralph` without `--monitor` in non-interactive environments.
### Container can't access the network
Docker Desktop may need network access enabled. Check Docker Desktop settings and firewall rules.
## What's in the Container
The Docker image includes all Ralph dependencies:
| Component | Version |
|-----------|---------|
| Debian | bookworm-slim |
| Bash | 5.2+ |
| Node.js | 20 LTS |
| jq | Latest |
| Git | Latest |
| tmux | Latest |
| GNU coreutils | Latest |
| Claude Code CLI | Latest |

View file

@ -13,6 +13,9 @@ Learn which files Ralph creates, which ones you should customize, and how they w
### [Writing Effective Requirements](03-writing-requirements.md) ### [Writing Effective Requirements](03-writing-requirements.md)
Best practices for writing PROMPT.md, when to use specs/, and how fix_plan.md evolves during development. Includes good and bad examples. Best practices for writing PROMPT.md, when to use specs/, and how fix_plan.md evolves during development. Includes good and bad examples.
### [Docker Setup (Windows & Cross-Platform)](04-docker-setup.md)
Run Ralph inside a Docker container on Windows, Linux, or macOS. Includes Docker Compose setup, file permissions, git integration, and troubleshooting.
## Example Projects ## Example Projects
Check out the [examples/](../../examples/) directory for complete, realistic project configurations: Check out the [examples/](../../examples/) directory for complete, realistic project configurations: