Add Docker support with comprehensive deployment options

- Add multi-stage Dockerfile with optimized builds for Go backend and Node.js frontend
- Create docker-entrypoint.sh script for managing both services with PM2
- Add .dockerignore for optimal build context
- Update README.md with Docker deployment documentation including:
  - Docker build and run instructions
  - Persistent data configuration with volume mounts
  - Complete environment variable reference table
  - Docker Compose example configuration

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
Arseniy Ivanov 2025-08-03 17:15:09 -04:00
parent 9cb513019d
commit 602452b162
4 changed files with 375 additions and 3 deletions

83
.dockerignore Normal file
View file

@ -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*

85
Dockerfile Normal file
View file

@ -0,0 +1,85 @@
# 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
RUN apk add --no-cache git
# Copy Go modules
COPY proxy/go.mod proxy/go.sum ./proxy/
WORKDIR /app/proxy
RUN go mod download
# Copy Go source code
COPY proxy/ ./
RUN go build -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 --only=production
# Copy web source code and build
COPY web/ ./
RUN npm run build
# Stage 3: Production Runtime
FROM node:20-alpine
WORKDIR /app
# Install process manager for running multiple services
RUN npm install -g pm2
# 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 --no-verbose --tries=1 --spider http://localhost:${PORT}/health || exit 1
# Start both services
CMD ["./docker-entrypoint.sh"]

View file

@ -22,12 +22,14 @@ Claude Code Proxy serves two 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
@ -57,7 +59,59 @@ Claude Code Proxy serves two 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
@ -100,6 +154,7 @@ make help # Show all commands
## Configuration
### Local Development
Create a `.env` file with:
```
PORT=3001
@ -109,6 +164,33 @@ ANTHROPIC_FORWARD_URL=https://api.anthropic.com
See `.env.example` for all available options.
### 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

122
docker-entrypoint.sh Normal file
View file

@ -0,0 +1,122 @@
#!/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..."
pm2 delete all 2>/dev/null || true
exit 0
}
# Trap signals for graceful shutdown
trap cleanup SIGTERM SIGINT
# Create PM2 ecosystem file
cat > /tmp/ecosystem.config.js << EOF
module.exports = {
apps: [
{
name: 'proxy-server',
script: './bin/proxy',
cwd: '/app',
env: {
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}'
},
error_file: '/dev/stderr',
out_file: '/dev/stdout',
log_file: '/dev/stdout',
time: true
},
{
name: 'web-server',
script: 'npm',
args: 'start',
cwd: '/app/web',
env: {
PORT: '${WEB_PORT}',
NODE_ENV: 'production'
},
error_file: '/dev/stderr',
out_file: '/dev/stdout',
log_file: '/dev/stdout',
time: true
}
]
};
EOF
echo "📊 Configuration:"
echo " - Proxy Server: http://localhost:${PORT}"
echo " - Web Dashboard: http://localhost:${WEB_PORT}"
echo " - Database: ${DB_PATH}"
echo " - Anthropic API: ${ANTHROPIC_FORWARD_URL}"
echo "========================================="
# Start services with PM2
echo "🔄 Starting proxy server..."
pm2 start /tmp/ecosystem.config.js --only proxy-server --no-daemon &
# Wait for proxy to be ready
echo "⏳ Waiting for proxy server to start..."
timeout=30
while [ $timeout -gt 0 ]; do
if wget --quiet --spider "http://localhost:${PORT}/health" 2>/dev/null; then
echo "✅ Proxy server is ready"
break
fi
sleep 1
timeout=$((timeout - 1))
done
if [ $timeout -eq 0 ]; then
echo "❌ Proxy server failed to start within 30 seconds"
exit 1
fi
echo "🔄 Starting web server..."
pm2 start /tmp/ecosystem.config.js --only web-server --no-daemon &
# Wait for web server to be ready
echo "⏳ Waiting for web server to start..."
timeout=30
while [ $timeout -gt 0 ]; do
if wget --quiet --spider "http://localhost:${WEB_PORT}" 2>/dev/null; then
echo "✅ Web server is ready"
break
fi
sleep 1
timeout=$((timeout - 1))
done
if [ $timeout -eq 0 ]; then
echo "❌ Web server failed to start within 30 seconds"
exit 1
fi
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 ""
# Keep container running and show logs
pm2 logs --raw