Skip to content
Merged

Dev #13

Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 13 additions & 4 deletions .env.example
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,17 @@ API_RELOAD=false
# SSL/HTTPS Configuration
ENABLE_HTTPS=false
HTTPS_PORT=443
SSL_CERT_FILE=/app/ssl/cert.pem
SSL_KEY_FILE=/app/ssl/key.pem
SSL_REDIRECT=false
# SSL_CA_CERTS=/app/ssl/ca.pem # Optional CA certificates

# Docker: Path to directory containing cert.pem and key.pem on the host
# The directory is mounted to /app/ssl/ inside the container automatically.
# Default is ./ssl (relative to docker-compose.yml)
# SSL_CERTS_PATH=/path/to/your/ssl/certs

# Non-Docker only: Absolute paths to certificate files (not needed for Docker)
# SSL_CERT_FILE=/path/to/cert.pem
# SSL_KEY_FILE=/path/to/key.pem
# SSL_CA_CERTS=/path/to/ca.pem

# Authentication Configuration
API_KEY=your-secure-api-key-here-change-this-in-production
Expand Down Expand Up @@ -44,6 +51,7 @@ MINIO_BUCKET=code-interpreter-files
MINIO_REGION=us-east-1

# Docker Configuration
DOCKER_IMAGE_REGISTRY=code-interpreter
# DOCKER_BASE_URL=unix://var/run/docker.sock
DOCKER_TIMEOUT=60
DOCKER_NETWORK_MODE=none
Expand All @@ -52,7 +60,8 @@ DOCKER_READ_ONLY=true
# Resource Limits - Execution
MAX_EXECUTION_TIME=30
MAX_MEMORY_MB=512
MAX_CPU_QUOTA=50000
MAX_CPUS=1
MAX_CPU_QUOTA=50000 #Deprecated
MAX_PROCESSES=32
MAX_OPEN_FILES=1024

Expand Down
2 changes: 2 additions & 0 deletions .github/workflows/docker-publish.yml
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ on:
push:
branches: ["main", "dev"]
tags: ["v*.*.*"]
workflow_dispatch:

env:
REGISTRY: ghcr.io
Expand Down Expand Up @@ -49,6 +50,7 @@ jobs:
with:
context: .
push: true
platforms: linux/amd64,linux/arm64
tags: ${{ steps.meta.outputs.tags }}
labels: ${{ steps.meta.outputs.labels }}
cache-from: type=gha
Expand Down
29 changes: 28 additions & 1 deletion .github/workflows/execution-env-publish.yml
Original file line number Diff line number Diff line change
Expand Up @@ -5,22 +5,33 @@ on:
branches: ["main", "dev"]
paths:
- "docker/**"
- ".github/workflows/execution-env-publish.yml"
workflow_dispatch:
inputs:
build_all:
description: 'Force build all images'
type: boolean
default: false

env:
REGISTRY: ghcr.io
IMAGE_BASE: ${{ github.repository }}
ALL_LANGUAGES: '["python", "nodejs", "go", "java", "c-cpp", "php", "rust", "fortran", "r", "d"]'

jobs:
filter:
runs-on: ubuntu-latest
outputs:
changes: ${{ steps.changes.outputs.changes }}
changes: ${{ steps.determine-targets.outputs.languages }}
steps:
- uses: actions/checkout@v4
- uses: dorny/paths-filter@v3
id: changes
with:
filters: |
rebuild_all:
- '.github/workflows/execution-env-publish.yml'
- 'docker/entrypoint.sh'
python:
- 'docker/python.Dockerfile'
- 'docker/repl_server.py'
Expand All @@ -44,6 +55,21 @@ jobs:
d:
- 'docker/d.Dockerfile'

- name: Determine targets
id: determine-targets
run: |
if [ "${{ github.event_name }}" == "workflow_dispatch" ] && [ "${{ github.event.inputs.build_all }}" == "true" ]; then
echo 'languages=${{ env.ALL_LANGUAGES }}' >> $GITHUB_OUTPUT
elif [ "${{ steps.changes.outputs.rebuild_all }}" == "true" ]; then
# If workflow or shared files changed, build everything
echo 'languages=${{ env.ALL_LANGUAGES }}' >> $GITHUB_OUTPUT
else
# Filter out rebuild_all from the changes list
CHANGES='${{ steps.changes.outputs.changes }}'
FILTERED=$(echo "$CHANGES" | jq -c '[.[] | select(. != "rebuild_all")]')
echo "languages=$FILTERED" >> $GITHUB_OUTPUT
fi

build-images:
needs: filter
if: ${{ needs.filter.outputs.changes != '[]' && needs.filter.outputs.changes != '' }}
Expand Down Expand Up @@ -92,6 +118,7 @@ jobs:
context: docker
file: docker/${{ matrix.language }}.Dockerfile
push: true
platforms: linux/amd64,linux/arm64
tags: ${{ steps.meta.outputs.tags }}
labels: ${{ steps.meta.outputs.labels }}
cache-from: type=gha
Expand Down
28 changes: 23 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ A secure, open-source code interpreter API that provides sandboxed code executio

## Quick Start

Get up and running in minutes using prebuilt Docker images.
Get up and running in minutes by building the execution environment.

1. **Clone the repository**

Expand All @@ -24,24 +24,42 @@ Get up and running in minutes using prebuilt Docker images.
# The default settings work out-of-the-box for local development
```

3. **Pull execution environment images**
3. **Prepare execution environment images**

You can either build the images locally (recommended) or pull pre-built images from GitHub Container Registry.

**Option A: Build locally (Recommended)**
```bash
# Build Python only (minimal)
./docker/build-images.sh -l python

# Or build all 12 languages
./docker/build-images.sh -p
```

**Option B: Pull from GHCR**
```bash
# Python only (minimal)
# Pull Python only
docker pull ghcr.io/usnavy13/librecodeinterpreter/python:latest

# Or pull all 12 languages
# Or pull the API and all languages
docker pull ghcr.io/usnavy13/librecodeinterpreter:latest
for lang in python nodejs go java c-cpp php rust r fortran d; do
docker pull ghcr.io/usnavy13/librecodeinterpreter/$lang:latest
done
```

4. **Start the API**

**Option A: Using local images (if you built them)**
```bash
docker compose up -d
```

> **Building from source?** See the [Development Guide](docs/DEVELOPMENT.md) for instructions on building images locally.
**Option B: Using pre-built images (if you pulled them)**
```bash
docker compose -f docker-compose.ghcr.yml up -d
```

The API will be available at `http://localhost:8000`.
Visit `http://localhost:8000/docs` for the interactive API documentation.
Expand Down
157 changes: 157 additions & 0 deletions docker-compose.ghcr.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,157 @@
services:
# Code Interpreter API
api:
image: ghcr.io/usnavy13/librecodeinterpreter:latest
container_name: code-interpreter-api
user: "1000:988" # Run as user with docker group access
cap_add:
- NET_ADMIN # Required for iptables management when WAN access is enabled
ports:
- "${API_PORT:-8000}:8000"
- "${HTTPS_PORT:-443}:443"
env_file:
- .env
environment:
# Container-specific overrides (these override .env values)
- API_HOST=0.0.0.0
- API_PORT=8000
- DOCKER_IMAGE_REGISTRY=ghcr.io/usnavy13/librecodeinterpreter
- DOCKER_IMAGE_TAG=${DOCKER_IMAGE_TAG:-latest}

# Service discovery (container names)
- REDIS_HOST=redis
- REDIS_PORT=6379
- MINIO_ENDPOINT=minio:9000

# Docker socket path inside container
- DOCKER_BASE_URL=unix://var/run/docker.sock

# SSL paths inside container
- SSL_CERT_FILE=/app/ssl/cert.pem
- SSL_KEY_FILE=/app/ssl/key.pem
volumes:
- /var/run/docker.sock:/var/run/docker.sock
- ./logs:/app/logs
- ./data:/app/data
- ${SSL_CERTS_PATH:-./ssl}:/app/ssl
depends_on:
- redis
- minio
networks:
- code-interpreter-network
restart: unless-stopped
stop_grace_period: 30s # Allow time to cleanup pooled containers
healthcheck:
test:
[
"CMD",
"sh",
"-c",
"curl -f -k https://localhost:443/health 2>/dev/null || curl -f http://localhost:8000/health 2>/dev/null || curl -f http://localhost:80/health || exit 1",
]
interval: 30s
timeout: 15s
retries: 3
start_period: 15s

# Redis for session management
redis:
image: redis:7-alpine
container_name: code-interpreter-redis
ports:
# Expose to localhost for CLI tools
- "127.0.0.1:6379:6379"
environment:
- REDIS_PASSWORD=${REDIS_PASSWORD:-}
command: >
sh -c "
if [ -n \"$$REDIS_PASSWORD\" ]; then
redis-server --requirepass $$REDIS_PASSWORD --appendonly yes --appendfsync everysec
else
redis-server --appendonly yes --appendfsync everysec
fi
"
volumes:
- redis-data:/data
- ./docker/redis/redis.conf:/usr/local/etc/redis/redis.conf:ro
networks:
- code-interpreter-network
restart: unless-stopped
healthcheck:
test: ["CMD", "redis-cli", "ping"]
interval: 30s
timeout: 10s
retries: 3

# MinIO for file storage
minio:
image: minio/minio:latest
container_name: code-interpreter-minio
ports:
# API port for local testing
- "127.0.0.1:9000:9000"
# Console only, bound to localhost (access via SSH tunnel)
- "127.0.0.1:${MINIO_CONSOLE_PORT:-9001}:9001"
environment:
- MINIO_ROOT_USER=${MINIO_ACCESS_KEY:-minioadmin}
- MINIO_ROOT_PASSWORD=${MINIO_SECRET_KEY:-minioadmin}
- MINIO_BROWSER_REDIRECT_URL=http://localhost:9001
command: server /data --console-address ":9001"
volumes:
- minio-data:/data
networks:
- code-interpreter-network
restart: unless-stopped
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:9000/minio/health/live"]
interval: 30s
timeout: 10s
retries: 3

# MinIO bucket initialization
minio-init:
image: minio/mc:latest
container_name: code-interpreter-minio-init
depends_on:
- minio
environment:
- MINIO_ENDPOINT=minio:9000
- MINIO_ACCESS_KEY=${MINIO_ACCESS_KEY:-minioadmin}
- MINIO_SECRET_KEY=${MINIO_SECRET_KEY:-minioadmin}
- MINIO_BUCKET=${MINIO_BUCKET:-code-interpreter-files}
entrypoint: >
/bin/sh -c " echo 'Waiting for MinIO to be ready...'; until mc alias set minio http://$$MINIO_ENDPOINT $$MINIO_ACCESS_KEY $$MINIO_SECRET_KEY; do
echo 'MinIO not ready, waiting...';
sleep 2;
done; echo 'MinIO is ready. Creating bucket if it does not exist...'; mc mb minio/$$MINIO_BUCKET --ignore-existing; echo 'Bucket setup complete.'; "
networks:
- code-interpreter-network

volumes:
redis-data:
driver: local
minio-data:
driver: local

networks:
code-interpreter-network:
driver: bridge
ipam:
config:
- subnet: 172.20.0.0/16

# WAN-only network for execution containers that need internet access
# This network is only created when ENABLE_WAN_ACCESS=true
code-interpreter-wan:
driver: bridge
ipam:
config:
- subnet: 172.30.0.0/16
driver_opts:
# Enable NAT for outbound internet access
com.docker.network.bridge.enable_ip_masquerade: "true"
# Disable inter-container communication
com.docker.network.bridge.enable_icc: "false"
labels:
com.code-interpreter.managed: "true"
com.code-interpreter.type: "wan-access"
2 changes: 1 addition & 1 deletion docker-compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ services:
- /var/run/docker.sock:/var/run/docker.sock
- ./logs:/app/logs
- ./data:/app/data
- ./ssl:/app/ssl
- ${SSL_CERTS_PATH:-./ssl}:/app/ssl
- ./dashboard:/app/dashboard
- ./src:/app/src
depends_on:
Expand Down
Loading
Loading