Skip to content

Commit 1a58800

Browse files
mkageniusclaude
andcommitted
Add Docker multi-platform build support
- GitHub Actions workflow for AMD64/ARM64 Docker builds - Docker Compose configuration for easy deployment - Comprehensive Docker setup documentation - Local build test script for validation Enables Docker Hub publishing alongside existing Apple container builds using separate tags (docker-latest vs apple-latest). 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
1 parent 6dacc6c commit 1a58800

File tree

4 files changed

+369
-0
lines changed

4 files changed

+369
-0
lines changed

.github/workflows/docker-build.yml

Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
name: Docker Multi-Platform Build
2+
3+
on:
4+
push:
5+
branches: [ main, develop ]
6+
pull_request:
7+
branches: [ main ]
8+
release:
9+
types: [ published ]
10+
11+
env:
12+
REGISTRY: docker.io
13+
IMAGE_NAME: instavm/coderunner
14+
15+
jobs:
16+
docker-build:
17+
runs-on: ubuntu-latest
18+
steps:
19+
- name: Checkout repository
20+
uses: actions/checkout@v4
21+
22+
- name: Set up Docker Buildx
23+
uses: docker/setup-buildx-action@v3
24+
25+
- name: Log in to Docker Hub
26+
if: github.event_name != 'pull_request'
27+
uses: docker/login-action@v3
28+
with:
29+
registry: ${{ env.REGISTRY }}
30+
username: ${{ secrets.DOCKER_USERNAME }}
31+
password: ${{ secrets.DOCKER_TOKEN }}
32+
33+
- name: Extract metadata
34+
id: meta
35+
uses: docker/metadata-action@v5
36+
with:
37+
images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}
38+
tags: |
39+
# Tag with 'docker-latest' for main branch
40+
type=raw,value=docker-latest,enable={{is_default_branch}}
41+
# Tag with branch name + 'docker' suffix
42+
type=ref,event=branch,suffix=-docker
43+
# Tag PRs with pr-<number>-docker
44+
type=ref,event=pr,suffix=-docker
45+
# Tag releases with version + 'docker' suffix
46+
type=semver,pattern={{version}}-docker
47+
type=semver,pattern={{major}}.{{minor}}-docker
48+
labels: |
49+
org.opencontainers.image.title=CodeRunner Docker
50+
org.opencontainers.image.description=CodeRunner MCP server for Docker/Linux environments
51+
org.opencontainers.image.vendor=InstVM
52+
53+
- name: Build and push Docker image
54+
uses: docker/build-push-action@v5
55+
with:
56+
context: .
57+
file: ./Dockerfile
58+
platforms: linux/amd64,linux/arm64
59+
push: ${{ github.event_name != 'pull_request' }}
60+
tags: ${{ steps.meta.outputs.tags }}
61+
labels: ${{ steps.meta.outputs.labels }}
62+
cache-from: type=gha
63+
cache-to: type=gha,mode=max
64+
65+
- name: Generate build summary
66+
run: |
67+
echo "## Docker Build Summary" >> $GITHUB_STEP_SUMMARY
68+
echo "- **Platforms**: linux/amd64, linux/arm64" >> $GITHUB_STEP_SUMMARY
69+
echo "- **Registry**: ${{ env.REGISTRY }}" >> $GITHUB_STEP_SUMMARY
70+
echo "- **Image**: ${{ env.IMAGE_NAME }}" >> $GITHUB_STEP_SUMMARY
71+
echo "- **Tags**: ${{ steps.meta.outputs.tags }}" >> $GITHUB_STEP_SUMMARY
72+
echo "" >> $GITHUB_STEP_SUMMARY
73+
echo "### Usage Examples" >> $GITHUB_STEP_SUMMARY
74+
echo '```bash' >> $GITHUB_STEP_SUMMARY
75+
echo "# Run with Docker" >> $GITHUB_STEP_SUMMARY
76+
echo "docker run -d -p 8222:8222 -v ./uploads:/app/uploads ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:docker-latest" >> $GITHUB_STEP_SUMMARY
77+
echo "" >> $GITHUB_STEP_SUMMARY
78+
echo "# Run with Docker Compose" >> $GITHUB_STEP_SUMMARY
79+
echo "# See docker-compose.yml in repository" >> $GITHUB_STEP_SUMMARY
80+
echo '```' >> $GITHUB_STEP_SUMMARY

DOCKER_SETUP.md

Lines changed: 130 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,130 @@
1+
# Docker Multi-Platform Setup
2+
3+
This document explains how to set up Docker builds and deployment for CodeRunner across multiple platforms.
4+
5+
## Required Secrets for GitHub Actions
6+
7+
To enable automatic Docker Hub publishing, add these secrets to your GitHub repository:
8+
9+
### Setting up Docker Hub Secrets
10+
11+
1. **Go to your Docker Hub account**:
12+
- Visit [hub.docker.com](https://hub.docker.com)
13+
- Go to Account Settings → Security → New Access Token
14+
- Create a token with Read, Write, Delete permissions
15+
16+
2. **Add secrets to GitHub repository**:
17+
- Go to your GitHub repo → Settings → Secrets and variables → Actions
18+
- Add these repository secrets:
19+
20+
```
21+
DOCKER_USERNAME: your-dockerhub-username
22+
DOCKER_TOKEN: your-dockerhub-access-token
23+
```
24+
25+
## Workflow Triggers
26+
27+
The Docker build workflow runs on:
28+
- **Push to main/develop**: Builds and pushes `docker-latest` tag
29+
- **Pull Requests**: Builds only (no push) for testing
30+
- **Releases**: Builds and pushes version tags like `v1.0.0-docker`
31+
32+
## Docker Usage
33+
34+
### Quick Start with Docker
35+
36+
```bash
37+
# Run CodeRunner with Docker
38+
docker run -d \
39+
--name coderunner \
40+
-p 8222:8222 \
41+
-v ./uploads:/app/uploads \
42+
instavm/coderunner:docker-latest
43+
44+
# Access MCP server
45+
curl http://localhost:8222/mcp
46+
```
47+
48+
### Docker Compose (Recommended)
49+
50+
```bash
51+
# Use the provided docker-compose.yml
52+
docker compose up -d
53+
54+
# View logs
55+
docker compose logs -f
56+
57+
# Stop service
58+
docker compose down
59+
```
60+
61+
### Environment Variables
62+
63+
- `FASTMCP_HOST`: Server host (default: 0.0.0.0)
64+
- `FASTMCP_PORT`: Server port (default: 8222)
65+
66+
## Platform Support
67+
68+
| Platform | Container Tool | Image Tag | Registry |
69+
|----------|----------------|-----------|----------|
70+
| macOS (Apple Silicon) | Apple `container` | `apple-latest` | OCI-compatible |
71+
| Linux (x64/ARM64) | Docker | `docker-latest` | Docker Hub |
72+
| Windows | Docker Desktop | `docker-latest` | Docker Hub |
73+
74+
## Integration Examples
75+
76+
### With Claude Desktop (Docker)
77+
```json
78+
{
79+
"mcpServers": {
80+
"coderunner": {
81+
"command": "docker",
82+
"args": [
83+
"run", "--rm", "-i",
84+
"-p", "8222:8222",
85+
"-v", "./uploads:/app/uploads",
86+
"instavm/coderunner:docker-latest"
87+
]
88+
}
89+
}
90+
}
91+
```
92+
93+
### With OpenAI Agents
94+
```python
95+
# Update openai_client.py to use Docker endpoint
96+
hostname = "localhost" # Instead of coderunner.local
97+
address = "127.0.0.1"
98+
url = f"http://{address}:8222/mcp"
99+
```
100+
101+
## Building Locally
102+
103+
```bash
104+
# Standard Docker build
105+
docker build -t coderunner-local .
106+
107+
# Multi-architecture build
108+
docker buildx build --platform linux/amd64,linux/arm64 -t coderunner-multiarch .
109+
```
110+
111+
## Troubleshooting
112+
113+
### Common Issues
114+
115+
1. **Port conflicts**: Change port mapping `-p 8223:8222`
116+
2. **Volume permissions**: Ensure `./uploads` directory exists and is writable
117+
3. **Memory issues**: Add memory limits `--memory 4g`
118+
119+
### Health Checks
120+
121+
```bash
122+
# Check container status
123+
docker ps
124+
125+
# Check logs
126+
docker logs coderunner
127+
128+
# Test MCP endpoint
129+
curl -f http://localhost:8222/mcp || echo "MCP not ready"
130+
```

docker-compose.yml

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
version: '3.8'
2+
3+
services:
4+
coderunner:
5+
image: instavm/coderunner:docker-latest
6+
container_name: coderunner
7+
ports:
8+
- "8222:8222"
9+
volumes:
10+
- ./uploads:/app/uploads
11+
environment:
12+
- FASTMCP_HOST=0.0.0.0
13+
- FASTMCP_PORT=8222
14+
restart: unless-stopped
15+
healthcheck:
16+
test: ["CMD", "curl", "-f", "http://localhost:8222/mcp"]
17+
interval: 30s
18+
timeout: 10s
19+
retries: 3
20+
start_period: 40s
21+
22+
volumes:
23+
uploads:
24+
driver: local

test-build.sh

Lines changed: 135 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,135 @@
1+
#!/bin/bash
2+
3+
# Test script for multi-platform container builds
4+
# Tests both Docker and Apple container builds locally
5+
6+
set -e
7+
8+
echo "🚀 CodeRunner Multi-Platform Build Test"
9+
echo "========================================"
10+
11+
# Colors for output
12+
RED='\033[0;31m'
13+
GREEN='\033[0;32m'
14+
YELLOW='\033[1;33m'
15+
NC='\033[0m' # No Color
16+
17+
# Function to print colored output
18+
print_status() {
19+
echo -e "${GREEN}$1${NC}"
20+
}
21+
22+
print_warning() {
23+
echo -e "${YELLOW}⚠️ $1${NC}"
24+
}
25+
26+
print_error() {
27+
echo -e "${RED}$1${NC}"
28+
}
29+
30+
# Check if we're on macOS
31+
if [[ "$OSTYPE" == "darwin"* ]]; then
32+
MACOS=true
33+
echo "🍎 macOS detected"
34+
else
35+
MACOS=false
36+
echo "🐧 Non-macOS system detected"
37+
fi
38+
39+
echo ""
40+
echo "1. Testing Docker Build"
41+
echo "----------------------"
42+
43+
# Check if Docker is available
44+
if ! command -v docker &> /dev/null; then
45+
print_error "Docker not found. Please install Docker."
46+
exit 1
47+
fi
48+
49+
print_status "Docker found: $(docker --version)"
50+
51+
# Test basic Docker build
52+
echo "Building with Docker..."
53+
if docker build -t coderunner-docker-test .; then
54+
print_status "Docker build successful"
55+
else
56+
print_error "Docker build failed"
57+
exit 1
58+
fi
59+
60+
# Test if the Docker image runs
61+
echo "Testing Docker container startup..."
62+
DOCKER_CONTAINER_ID=$(docker run -d -p 8223:8222 coderunner-docker-test)
63+
sleep 5
64+
65+
# Check if container is running
66+
if docker ps | grep -q "$DOCKER_CONTAINER_ID"; then
67+
print_status "Docker container started successfully"
68+
69+
# Test MCP endpoint (basic connectivity test)
70+
if curl -s --fail --connect-timeout 5 http://localhost:8223/mcp > /dev/null; then
71+
print_status "MCP endpoint responding on Docker container"
72+
else
73+
print_warning "MCP endpoint not responding (may need more startup time)"
74+
fi
75+
76+
# Cleanup
77+
docker stop "$DOCKER_CONTAINER_ID" > /dev/null
78+
print_status "Docker container stopped and cleaned up"
79+
else
80+
print_error "Docker container failed to start"
81+
fi
82+
83+
echo ""
84+
echo "2. Testing Docker Multi-Architecture Build"
85+
echo "-----------------------------------------"
86+
87+
# Check if buildx is available
88+
if docker buildx version &> /dev/null; then
89+
print_status "Docker buildx found"
90+
91+
# Create builder if it doesn't exist
92+
if ! docker buildx inspect multiarch-builder &> /dev/null; then
93+
echo "Creating multi-arch builder..."
94+
docker buildx create --name multiarch-builder --use
95+
else
96+
docker buildx use multiarch-builder
97+
fi
98+
99+
# Test multi-arch build (without pushing)
100+
echo "Testing multi-architecture build..."
101+
if docker buildx build --platform linux/amd64,linux/arm64 -t coderunner-multiarch .; then
102+
print_status "Multi-architecture build successful"
103+
else
104+
print_error "Multi-architecture build failed"
105+
fi
106+
else
107+
print_warning "Docker buildx not available - skipping multi-arch test"
108+
fi
109+
110+
# Skip Apple container test for now
111+
if $MACOS; then
112+
echo ""
113+
echo "3. Apple Container Build (SKIPPED)"
114+
echo "---------------------------------"
115+
print_warning "Apple container test skipped - focusing on Docker builds"
116+
fi
117+
118+
echo ""
119+
echo "4. Build Comparison Summary"
120+
echo "=========================="
121+
122+
echo "Docker image size:"
123+
docker images coderunner-docker-test --format "table {{.Repository}}\t{{.Tag}}\t{{.Size}}"
124+
125+
# Apple container comparison skipped
126+
127+
echo ""
128+
echo "🎉 Build test completed!"
129+
echo ""
130+
echo "Next steps:"
131+
echo "- If builds are successful, you can push to registries:"
132+
echo " Docker: docker tag coderunner-docker-test instavm/coderunner:docker-latest"
133+
echo " Apple: container images tag coderunner-apple-test instavm/coderunner:apple-latest"
134+
echo "- Set up automated builds with GitHub Actions"
135+
echo "- Update documentation with multi-platform instructions"

0 commit comments

Comments
 (0)