diff --git a/.dockerignore b/.dockerignore new file mode 100644 index 0000000..ac2e52d --- /dev/null +++ b/.dockerignore @@ -0,0 +1,83 @@ +# Docker ignore file for Claude Code Proxy +# Excludes unnecessary files from Docker build context + +# Git +.git +.gitignore +.gitattributes + +# Docker +Dockerfile +.dockerignore +docker-compose*.yml + +# Documentation +README.md +*.md +demo.gif + +# Environment and config +.env +.env.local +.env.example + +# Build artifacts +bin/ +build/ +dist/ +target/ + +# Dependencies +node_modules/ +vendor/ + +# Cache and temporary files +.cache/ +.temp/ +.tmp/ +*.tmp +*.log + +# IDE and editor files +.vscode/ +.idea/ +*.swp +*.swo +*~ + +# OS generated files +.DS_Store +.DS_Store? +._* +.Spotlight-V100 +.Trashes +ehthumbs.db +Thumbs.db + +# Database files (will be created in container) +*.db +*.sqlite +*.sqlite3 +requests/ + +# Web specific +web/.cache/ +web/build/ +web/dist/ +web/node_modules/ +web/npm-debug.log* +web/yarn-debug.log* +web/yarn-error.log* + +# Go specific +proxy/vendor/ +*.test +*.prof +coverage.txt + +# Logs +logs/ +*.log +npm-debug.log* +yarn-debug.log* +yarn-error.log* \ No newline at end of file diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..6891ded --- /dev/null +++ b/Dockerfile @@ -0,0 +1,89 @@ +# Multi-stage Dockerfile for Claude Code Proxy +# Builds both Go proxy server and Remix frontend in a single container + +# Stage 1: Build Go Backend +FROM golang:1.21-alpine AS go-builder + +WORKDIR /app + +# Install build dependencies including gcc for CGO +RUN apk add --no-cache git gcc musl-dev sqlite-dev + +# Copy Go modules +COPY proxy/go.mod proxy/go.sum ./proxy/ +WORKDIR /app/proxy +RUN go mod download + +# Copy Go source code +COPY proxy/ ./ +# Build with CGO enabled for SQLite support +RUN CGO_ENABLED=1 GOOS=linux go build -a -installsuffix cgo -o /app/bin/proxy cmd/proxy/main.go + +# Stage 2: Build Node.js Frontend +FROM node:20-alpine AS node-builder + +WORKDIR /app + +# Copy package files +COPY web/package*.json ./web/ +WORKDIR /app/web +RUN npm ci + +# Copy web source code and build +COPY web/ ./ +RUN npm run build + +# Clean up dev dependencies after build +RUN npm ci --only=production && npm cache clean --force + +# Stage 3: Production Runtime +FROM node:20-alpine + +WORKDIR /app + +# Install runtime dependencies +RUN apk add --no-cache sqlite wget + +# Create app user for security +RUN addgroup -g 1001 -S appgroup && \ + adduser -S appuser -u 1001 -G appgroup + +# Copy built Go binary +COPY --from=go-builder /app/bin/proxy ./bin/proxy +RUN chmod +x ./bin/proxy + +# Copy built Remix application +COPY --from=node-builder /app/web/build ./web/build +COPY --from=node-builder /app/web/package*.json ./web/ +COPY --from=node-builder /app/web/node_modules ./web/node_modules + +# Create data directory for SQLite database +RUN mkdir -p /app/data && chown -R appuser:appgroup /app + +# Copy startup script +COPY docker-entrypoint.sh ./ +RUN chmod +x docker-entrypoint.sh + +# Environment variables with defaults +ENV PORT=3001 +ENV WEB_PORT=5173 +ENV READ_TIMEOUT=600 +ENV WRITE_TIMEOUT=600 +ENV IDLE_TIMEOUT=600 +ENV ANTHROPIC_FORWARD_URL=https://api.anthropic.com +ENV ANTHROPIC_VERSION=2023-06-01 +ENV ANTHROPIC_MAX_RETRIES=3 +ENV DB_PATH=/app/data/requests.db + +# Expose ports +EXPOSE 3001 5173 + +# Switch to app user +USER appuser + +# Health check +HEALTHCHECK --interval=30s --timeout=10s --start-period=5s --retries=3 \ + CMD wget -qO- http://localhost:3001/health > /dev/null || exit 1 + +# Start both services +CMD ["./docker-entrypoint.sh"] \ No newline at end of file diff --git a/README.md b/README.md index eee3c8d..30739c7 100644 --- a/README.md +++ b/README.md @@ -24,12 +24,14 @@ Claude Code Proxy serves three main purposes: ## Quick Start ### Prerequisites -- Go 1.20+ -- Node.js 18+ +- **Option 1**: Go 1.20+ and Node.js 18+ (for local development) +- **Option 2**: Docker (for containerized deployment) - Claude Code ### Installation +#### Option 1: Local Development + 1. **Clone the repository** ```bash git clone https://github.com/seifghazi/claude-code-proxy.git @@ -54,7 +56,59 @@ Claude Code Proxy serves three main purposes: ./run.sh ``` -5. **Using with Claude Code** +#### Option 2: Docker + +1. **Clone the repository** + ```bash + git clone https://github.com/seifghazi/claude-code-proxy.git + cd claude-code-proxy + ``` + +2. **Build and run with Docker** + ```bash + # Build the image + docker build -t claude-code-proxy . + + # Run with default settings + docker run -p 3001:3001 -p 5173:5173 claude-code-proxy + ``` + +3. **Run with persistent data and custom configuration** + ```bash + # Create a data directory for persistent SQLite database + mkdir -p ./data + + # Run with volume mount and custom environment variables + docker run -p 3001:3001 -p 5173:5173 \ + -v ./data:/app/data \ + -e ANTHROPIC_FORWARD_URL=https://api.anthropic.com \ + -e PORT=3001 \ + -e WEB_PORT=5173 \ + claude-code-proxy + ``` + +4. **Docker Compose (alternative)** + ```yaml + # docker-compose.yml + version: '3.8' + services: + claude-code-proxy: + build: . + ports: + - "3001:3001" + - "5173:5173" + volumes: + - ./data:/app/data + environment: + - ANTHROPIC_FORWARD_URL=https://api.anthropic.com + - PORT=3001 + - WEB_PORT=5173 + - DB_PATH=/app/data/requests.db + ``` + + Then run: `docker-compose up` + +### Using with Claude Code To use this proxy with Claude Code, set: ```bash @@ -178,6 +232,33 @@ Override config via environment: - `DB_PATH` - Database path - `SUBAGENT_MAPPINGS` - Comma-separated mappings (e.g., `"code-reviewer:gpt-4o,data-analyst:o3"`) +### Docker Environment Variables + +All environment variables can be configured when running the Docker container: + +| Variable | Default | Description | +|----------|---------|-------------| +| `PORT` | `3001` | Proxy server port | +| `WEB_PORT` | `5173` | Web dashboard port | +| `READ_TIMEOUT` | `600` | Server read timeout (seconds) | +| `WRITE_TIMEOUT` | `600` | Server write timeout (seconds) | +| `IDLE_TIMEOUT` | `600` | Server idle timeout (seconds) | +| `ANTHROPIC_FORWARD_URL` | `https://api.anthropic.com` | Target Anthropic API URL | +| `ANTHROPIC_VERSION` | `2023-06-01` | Anthropic API version | +| `ANTHROPIC_MAX_RETRIES` | `3` | Maximum retry attempts | +| `DB_PATH` | `/app/data/requests.db` | SQLite database path | + +Example with custom configuration: +```bash +docker run -p 3001:3001 -p 5173:5173 \ + -v ./data:/app/data \ + -e PORT=8080 \ + -e WEB_PORT=3000 \ + -e ANTHROPIC_FORWARD_URL=https://api.anthropic.com \ + -e DB_PATH=/app/data/custom.db \ + claude-code-proxy +``` + ## Project Structure diff --git a/docker-entrypoint.sh b/docker-entrypoint.sh new file mode 100644 index 0000000..1ea9e68 --- /dev/null +++ b/docker-entrypoint.sh @@ -0,0 +1,63 @@ +#!/bin/sh + +# Docker entrypoint script for Claude Code Proxy +# Starts both the Go proxy server and Remix frontend + +set -e + +echo "🚀 Starting Claude Code Proxy services..." +echo "=========================================" + +# Function to handle graceful shutdown +cleanup() { + echo "" + echo "🛑 Shutting down services..." + kill $PROXY_PID $WEB_PID 2>/dev/null || true + exit 0 +} + +# Trap signals for graceful shutdown +trap cleanup SIGTERM SIGINT + +echo "📊 Configuration:" +echo " - Proxy Server: http://0.0.0.0:${PORT}" +echo " - Web Dashboard: http://0.0.0.0:${WEB_PORT}" +echo " - Database: ${DB_PATH}" +echo " - Anthropic API: ${ANTHROPIC_FORWARD_URL}" +echo "=========================================" + +# Start proxy server +echo "🔄 Starting proxy server..." +PORT=${PORT} \ +READ_TIMEOUT=${READ_TIMEOUT}s \ +WRITE_TIMEOUT=${WRITE_TIMEOUT}s \ +IDLE_TIMEOUT=${IDLE_TIMEOUT}s \ +ANTHROPIC_FORWARD_URL=${ANTHROPIC_FORWARD_URL} \ +ANTHROPIC_VERSION=${ANTHROPIC_VERSION} \ +ANTHROPIC_MAX_RETRIES=${ANTHROPIC_MAX_RETRIES} \ +DB_PATH=${DB_PATH} \ +./bin/proxy & +PROXY_PID=$! + +# Wait for proxy to start +sleep 3 + +# Start web server +echo "🔄 Starting web server..." +cd web +PORT=${WEB_PORT} HOST=0.0.0.0 NODE_ENV=production npx remix-serve build/server/index.js & +WEB_PID=$! +cd .. + +echo "" +echo "✨ All services started successfully!" +echo "=========================================" +echo "📊 Web Dashboard: http://localhost:${WEB_PORT}" +echo "🔌 API Proxy: http://localhost:${PORT}" +echo "💚 Health Check: http://localhost:${PORT}/health" +echo "=========================================" +echo "💡 To use with Claude Code, set: ANTHROPIC_BASE_URL=http://localhost:${PORT}" +echo "" + +# Wait for processes to finish +wait \ No newline at end of file