Skip to content

Commit f319fa1

Browse files
authored
Merge pull request #13 from usnavy13/dev
Dev
2 parents ba516ec + a14ddea commit f319fa1

39 files changed

Lines changed: 444 additions & 176 deletions

.env.example

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -9,10 +9,17 @@ API_RELOAD=false
99
# SSL/HTTPS Configuration
1010
ENABLE_HTTPS=false
1111
HTTPS_PORT=443
12-
SSL_CERT_FILE=/app/ssl/cert.pem
13-
SSL_KEY_FILE=/app/ssl/key.pem
1412
SSL_REDIRECT=false
15-
# SSL_CA_CERTS=/app/ssl/ca.pem # Optional CA certificates
13+
14+
# Docker: Path to directory containing cert.pem and key.pem on the host
15+
# The directory is mounted to /app/ssl/ inside the container automatically.
16+
# Default is ./ssl (relative to docker-compose.yml)
17+
# SSL_CERTS_PATH=/path/to/your/ssl/certs
18+
19+
# Non-Docker only: Absolute paths to certificate files (not needed for Docker)
20+
# SSL_CERT_FILE=/path/to/cert.pem
21+
# SSL_KEY_FILE=/path/to/key.pem
22+
# SSL_CA_CERTS=/path/to/ca.pem
1623

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

4653
# Docker Configuration
54+
DOCKER_IMAGE_REGISTRY=code-interpreter
4755
# DOCKER_BASE_URL=unix://var/run/docker.sock
4856
DOCKER_TIMEOUT=60
4957
DOCKER_NETWORK_MODE=none
@@ -52,7 +60,8 @@ DOCKER_READ_ONLY=true
5260
# Resource Limits - Execution
5361
MAX_EXECUTION_TIME=30
5462
MAX_MEMORY_MB=512
55-
MAX_CPU_QUOTA=50000
63+
MAX_CPUS=1
64+
MAX_CPU_QUOTA=50000 #Deprecated
5665
MAX_PROCESSES=32
5766
MAX_OPEN_FILES=1024
5867

.github/workflows/docker-publish.yml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ on:
44
push:
55
branches: ["main", "dev"]
66
tags: ["v*.*.*"]
7+
workflow_dispatch:
78

89
env:
910
REGISTRY: ghcr.io
@@ -49,6 +50,7 @@ jobs:
4950
with:
5051
context: .
5152
push: true
53+
platforms: linux/amd64,linux/arm64
5254
tags: ${{ steps.meta.outputs.tags }}
5355
labels: ${{ steps.meta.outputs.labels }}
5456
cache-from: type=gha

.github/workflows/execution-env-publish.yml

Lines changed: 28 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,22 +5,33 @@ on:
55
branches: ["main", "dev"]
66
paths:
77
- "docker/**"
8+
- ".github/workflows/execution-env-publish.yml"
9+
workflow_dispatch:
10+
inputs:
11+
build_all:
12+
description: 'Force build all images'
13+
type: boolean
14+
default: false
815

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

1321
jobs:
1422
filter:
1523
runs-on: ubuntu-latest
1624
outputs:
17-
changes: ${{ steps.changes.outputs.changes }}
25+
changes: ${{ steps.determine-targets.outputs.languages }}
1826
steps:
1927
- uses: actions/checkout@v4
2028
- uses: dorny/paths-filter@v3
2129
id: changes
2230
with:
2331
filters: |
32+
rebuild_all:
33+
- '.github/workflows/execution-env-publish.yml'
34+
- 'docker/entrypoint.sh'
2435
python:
2536
- 'docker/python.Dockerfile'
2637
- 'docker/repl_server.py'
@@ -44,6 +55,21 @@ jobs:
4455
d:
4556
- 'docker/d.Dockerfile'
4657
58+
- name: Determine targets
59+
id: determine-targets
60+
run: |
61+
if [ "${{ github.event_name }}" == "workflow_dispatch" ] && [ "${{ github.event.inputs.build_all }}" == "true" ]; then
62+
echo 'languages=${{ env.ALL_LANGUAGES }}' >> $GITHUB_OUTPUT
63+
elif [ "${{ steps.changes.outputs.rebuild_all }}" == "true" ]; then
64+
# If workflow or shared files changed, build everything
65+
echo 'languages=${{ env.ALL_LANGUAGES }}' >> $GITHUB_OUTPUT
66+
else
67+
# Filter out rebuild_all from the changes list
68+
CHANGES='${{ steps.changes.outputs.changes }}'
69+
FILTERED=$(echo "$CHANGES" | jq -c '[.[] | select(. != "rebuild_all")]')
70+
echo "languages=$FILTERED" >> $GITHUB_OUTPUT
71+
fi
72+
4773
build-images:
4874
needs: filter
4975
if: ${{ needs.filter.outputs.changes != '[]' && needs.filter.outputs.changes != '' }}
@@ -92,6 +118,7 @@ jobs:
92118
context: docker
93119
file: docker/${{ matrix.language }}.Dockerfile
94120
push: true
121+
platforms: linux/amd64,linux/arm64
95122
tags: ${{ steps.meta.outputs.tags }}
96123
labels: ${{ steps.meta.outputs.labels }}
97124
cache-from: type=gha

README.md

Lines changed: 23 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ A secure, open-source code interpreter API that provides sandboxed code executio
88

99
## Quick Start
1010

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

1313
1. **Clone the repository**
1414

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

27-
3. **Pull execution environment images**
27+
3. **Prepare execution environment images**
2828

29+
You can either build the images locally (recommended) or pull pre-built images from GitHub Container Registry.
30+
31+
**Option A: Build locally (Recommended)**
32+
```bash
33+
# Build Python only (minimal)
34+
./docker/build-images.sh -l python
35+
36+
# Or build all 12 languages
37+
./docker/build-images.sh -p
38+
```
39+
40+
**Option B: Pull from GHCR**
2941
```bash
30-
# Python only (minimal)
42+
# Pull Python only
3143
docker pull ghcr.io/usnavy13/librecodeinterpreter/python:latest
3244

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

3952
4. **Start the API**
53+
54+
**Option A: Using local images (if you built them)**
4055
```bash
4156
docker compose up -d
4257
```
4358

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

4664
The API will be available at `http://localhost:8000`.
4765
Visit `http://localhost:8000/docs` for the interactive API documentation.

docker-compose.ghcr.yml

Lines changed: 157 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,157 @@
1+
services:
2+
# Code Interpreter API
3+
api:
4+
image: ghcr.io/usnavy13/librecodeinterpreter:latest
5+
container_name: code-interpreter-api
6+
user: "1000:988" # Run as user with docker group access
7+
cap_add:
8+
- NET_ADMIN # Required for iptables management when WAN access is enabled
9+
ports:
10+
- "${API_PORT:-8000}:8000"
11+
- "${HTTPS_PORT:-443}:443"
12+
env_file:
13+
- .env
14+
environment:
15+
# Container-specific overrides (these override .env values)
16+
- API_HOST=0.0.0.0
17+
- API_PORT=8000
18+
- DOCKER_IMAGE_REGISTRY=ghcr.io/usnavy13/librecodeinterpreter
19+
- DOCKER_IMAGE_TAG=${DOCKER_IMAGE_TAG:-latest}
20+
21+
# Service discovery (container names)
22+
- REDIS_HOST=redis
23+
- REDIS_PORT=6379
24+
- MINIO_ENDPOINT=minio:9000
25+
26+
# Docker socket path inside container
27+
- DOCKER_BASE_URL=unix://var/run/docker.sock
28+
29+
# SSL paths inside container
30+
- SSL_CERT_FILE=/app/ssl/cert.pem
31+
- SSL_KEY_FILE=/app/ssl/key.pem
32+
volumes:
33+
- /var/run/docker.sock:/var/run/docker.sock
34+
- ./logs:/app/logs
35+
- ./data:/app/data
36+
- ${SSL_CERTS_PATH:-./ssl}:/app/ssl
37+
depends_on:
38+
- redis
39+
- minio
40+
networks:
41+
- code-interpreter-network
42+
restart: unless-stopped
43+
stop_grace_period: 30s # Allow time to cleanup pooled containers
44+
healthcheck:
45+
test:
46+
[
47+
"CMD",
48+
"sh",
49+
"-c",
50+
"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",
51+
]
52+
interval: 30s
53+
timeout: 15s
54+
retries: 3
55+
start_period: 15s
56+
57+
# Redis for session management
58+
redis:
59+
image: redis:7-alpine
60+
container_name: code-interpreter-redis
61+
ports:
62+
# Expose to localhost for CLI tools
63+
- "127.0.0.1:6379:6379"
64+
environment:
65+
- REDIS_PASSWORD=${REDIS_PASSWORD:-}
66+
command: >
67+
sh -c "
68+
if [ -n \"$$REDIS_PASSWORD\" ]; then
69+
redis-server --requirepass $$REDIS_PASSWORD --appendonly yes --appendfsync everysec
70+
else
71+
redis-server --appendonly yes --appendfsync everysec
72+
fi
73+
"
74+
volumes:
75+
- redis-data:/data
76+
- ./docker/redis/redis.conf:/usr/local/etc/redis/redis.conf:ro
77+
networks:
78+
- code-interpreter-network
79+
restart: unless-stopped
80+
healthcheck:
81+
test: ["CMD", "redis-cli", "ping"]
82+
interval: 30s
83+
timeout: 10s
84+
retries: 3
85+
86+
# MinIO for file storage
87+
minio:
88+
image: minio/minio:latest
89+
container_name: code-interpreter-minio
90+
ports:
91+
# API port for local testing
92+
- "127.0.0.1:9000:9000"
93+
# Console only, bound to localhost (access via SSH tunnel)
94+
- "127.0.0.1:${MINIO_CONSOLE_PORT:-9001}:9001"
95+
environment:
96+
- MINIO_ROOT_USER=${MINIO_ACCESS_KEY:-minioadmin}
97+
- MINIO_ROOT_PASSWORD=${MINIO_SECRET_KEY:-minioadmin}
98+
- MINIO_BROWSER_REDIRECT_URL=http://localhost:9001
99+
command: server /data --console-address ":9001"
100+
volumes:
101+
- minio-data:/data
102+
networks:
103+
- code-interpreter-network
104+
restart: unless-stopped
105+
healthcheck:
106+
test: ["CMD", "curl", "-f", "http://localhost:9000/minio/health/live"]
107+
interval: 30s
108+
timeout: 10s
109+
retries: 3
110+
111+
# MinIO bucket initialization
112+
minio-init:
113+
image: minio/mc:latest
114+
container_name: code-interpreter-minio-init
115+
depends_on:
116+
- minio
117+
environment:
118+
- MINIO_ENDPOINT=minio:9000
119+
- MINIO_ACCESS_KEY=${MINIO_ACCESS_KEY:-minioadmin}
120+
- MINIO_SECRET_KEY=${MINIO_SECRET_KEY:-minioadmin}
121+
- MINIO_BUCKET=${MINIO_BUCKET:-code-interpreter-files}
122+
entrypoint: >
123+
/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
124+
echo 'MinIO not ready, waiting...';
125+
sleep 2;
126+
done; echo 'MinIO is ready. Creating bucket if it does not exist...'; mc mb minio/$$MINIO_BUCKET --ignore-existing; echo 'Bucket setup complete.'; "
127+
networks:
128+
- code-interpreter-network
129+
130+
volumes:
131+
redis-data:
132+
driver: local
133+
minio-data:
134+
driver: local
135+
136+
networks:
137+
code-interpreter-network:
138+
driver: bridge
139+
ipam:
140+
config:
141+
- subnet: 172.20.0.0/16
142+
143+
# WAN-only network for execution containers that need internet access
144+
# This network is only created when ENABLE_WAN_ACCESS=true
145+
code-interpreter-wan:
146+
driver: bridge
147+
ipam:
148+
config:
149+
- subnet: 172.30.0.0/16
150+
driver_opts:
151+
# Enable NAT for outbound internet access
152+
com.docker.network.bridge.enable_ip_masquerade: "true"
153+
# Disable inter-container communication
154+
com.docker.network.bridge.enable_icc: "false"
155+
labels:
156+
com.code-interpreter.managed: "true"
157+
com.code-interpreter.type: "wan-access"

docker-compose.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ services:
3737
- /var/run/docker.sock:/var/run/docker.sock
3838
- ./logs:/app/logs
3939
- ./data:/app/data
40-
- ./ssl:/app/ssl
40+
- ${SSL_CERTS_PATH:-./ssl}:/app/ssl
4141
- ./dashboard:/app/dashboard
4242
- ./src:/app/src
4343
depends_on:

0 commit comments

Comments
 (0)