Configuration
Every environment variable, grouped and explained.
code-runner is configured entirely by environment variables — there are no config
endpoints. Copy .env.example to .env and adjust. Every default is safe for local
development; the ones you must change before production are flagged.
Core / auth
| Variable | Default | Description |
|---|---|---|
EXECUTOR_API_TOKEN | dev-insecure-token-change-me | Bearer token for the API. Change in prod — openssl rand -hex 32. |
REDIS_URL | redis://redis:6379 | Redis connection. Native TCP only for the worker (see below). |
API_PORT | 8080 | API listen port. |
MAX_QUEUE_DEPTH | 256 | POST /v1/execute returns 429 when LLEN(jobs:queue) >= this. |
soketi
| Variable | Default | Description |
|---|---|---|
SOKETI_HOST | soketi | soketi hostname. |
SOKETI_PORT | 6001 | soketi port. |
SOKETI_USE_TLS | false | true to connect over TLS. |
SOKETI_APP_ID | code-runner | Pusher app ID. |
SOKETI_APP_KEY | code-runner-key | Pusher app key — public, given to browser clients. |
SOKETI_APP_SECRET | code-runner-secret | Pusher app secret. Never returned by any endpoint, never written to Redis. Change in prod. |
Worker
| Variable | Default | Description |
|---|---|---|
WORKER_MAX_SANDBOXES | 8 | Max concurrent live sandboxes per worker node. |
DOCKER_HOST | unix:///var/run/docker.sock | Docker endpoint. No Docker-in-Docker. |
SANDBOX_RUNTIME | (unset = runc) | Set to runsc to run sandboxes under gVisor. |
WORKER_WARMUP_MS | 30000 | Slot reclaim timeout: if /start never arrives after /execute, the slot is freed. |
WORKER_HEARTBEAT_INTERVAL_MS | 5000 | How often the worker writes its heartbeat key. |
WORKER_HEARTBEAT_TTL_MS | 20000 | TTL on the heartbeat key. Must be several times the interval. |
Object storage / artifacts
All optional. With no bucket configured, file-artifact capture is disabled (pullable stdout/stderr still works). See Artifacts.
| Variable | Default | Description |
|---|---|---|
AWS_ENDPOINT_URL_S3 | http://minio:9000 (dev) | S3 endpoint (MinIO dev, Tigris/S3/R2 prod). |
ARTIFACT_S3_PUBLIC_ENDPOINT | (unset) | Endpoint used to sign presigned GET URLs when clients fetch from a different host than the worker connects to (split-horizon). When set, the worker uploads via AWS_ENDPOINT_URL_S3 but signs against this. See Artifacts. |
BUCKET_NAME | code-runner-artifacts | Bucket name. Auto-created on worker boot. |
AWS_ACCESS_KEY_ID | minioadmin (dev) | S3 access key. |
AWS_SECRET_ACCESS_KEY | minioadmin (dev) | S3 secret key. |
AWS_REGION | us-east-1 | Bucket region. |
RUN_RESULT_TTL | 600 | Redis TTL on the RunResult (seconds). |
PRESIGNED_URL_TTL | 86400 | Presigned artifact URL expiry (seconds, 24h). |
ARTIFACT_S3_OBJECT_TTL | 3 | S3 lifecycle object expiry (days). Must be ≥ the presigned-URL TTL. |
Each storage variable has an ARTIFACT_S3_* override (e.g. ARTIFACT_S3_BUCKET)
if you'd rather not reuse the standard AWS_* names.
Stub (local demo only)
| Variable | Default | Description |
|---|---|---|
API_BASE_URL | http://api:8080 | API base URL as seen by the stub inside compose. |
CHANNEL_AUTH_URL | http://api:8080/v1/channel-auth | Channel-auth endpoint the stub uses. |
ENABLE_CHANNEL_AUTH | true | Register the optional POST /v1/channel-auth helper. |
OpenTelemetry (off by default)
Telemetry emits nothing until OTEL_EXPORTER_OTLP_ENDPOINT is set. See
Observability.
| Variable | Default | Description |
|---|---|---|
OTEL_EXPORTER_OTLP_ENDPOINT | (unset = off) | The ON switch. Point at an OTLP collector. |
OTEL_EXPORTER_OTLP_PROTOCOL | http/protobuf | http/protobuf (:4318) or grpc (:4317). |
OTEL_SERVICE_NAME_API | code-runner-api | service.name for the API. |
OTEL_SERVICE_NAME_WORKER | code-runner-worker | service.name for the worker. |
OTEL_RESOURCE_ATTRIBUTES | service.namespace=code-runner | Resource attributes on every signal. |
OTEL_TRACES_SAMPLER | parentbased_traceidratio | Sampler; honors the caller's decision. |
OTEL_TRACES_SAMPLER_ARG | 1.0 | Sampling ratio. Lower in prod (e.g. 0.05). |
OTEL_SDK_DISABLED | (unset) | true hard-disables the SDK regardless of endpoint. |
Redis
The worker requires native TCP Redis
The worker uses blocking BRPOP and SUBSCRIBE, which need a persistent TCP
connection. Serverless REST-only Redis (e.g. Upstash's REST tier) cannot serve
the worker — it has no way to hold a connection open for server-push. It is fine for
the API (one-shot LPUSH/GET/SET).
Run a single native Redis/Valkey shared by both: self-hosted, Redis Cloud,
ElastiCache/MemoryDB, or an Upstash dedicated (non-REST) cluster. The constraint
is encoded as Config.RequiresNativeRedis() in the worker.
Production checklist
-
EXECUTOR_API_TOKEN— a real random token. -
SOKETI_APP_SECRET(and ideally_APP_KEY/_APP_ID) — real secrets. -
REDIS_URL— a native TCP Redis reachable by both API and worker. -
OTEL_TRACES_SAMPLER_ARG— lowered (e.g.0.05) if telemetry is on. -
WORKER_MAX_SANDBOXES— tuned to the node's CPU/memory. - Consider
SANDBOX_RUNTIME=runscfor an extra isolation layer.