Code Interpreter
Deployment

Docker Compose

Running the stack on a single host, including the scalable topology and image publishing.

The default stack

docker compose up --build

This builds every image from source and brings up nine services:

ServiceContainerPublished portRole
apiapi3112Public HTTP API
service-workerservice-workern/aJob consumer
sandbox-runnersandbox-runner2000Executes code
file_serverfile_server13000 → 3000Object storage front end
tool_call_servertool_call_servern/aTool call routing
egress_gatewayegress_gateway3190Sandbox egress control
package_initpackage_initn/aOne-shot runtime installer
redisredis16379 → 6379Queue and session pointers
miniominio19000, 19001S3-compatible storage

Only api is meant to be reachable by clients. The others are published locally for debugging convenience; in any real deployment they belong on an internal network. Override the host ports with CODEAPI_FILE_SERVER_PORT, CODEAPI_REDIS_PORT, CODEAPI_MINIO_PORT, and CODEAPI_MINIO_CONSOLE_PORT.

First start

package_init runs once and downloads the language runtimes into ./data/pkgs (override with SANDBOX_PACKAGES_PATH). Nothing is installed on the host itself. Everything else waits for it:

  • sandbox-runner has depends_on: package_init: service_completed_successfully
  • service-worker waits for sandbox-runner to report healthy

The runtime downloads are verified against SHA-256 checksums pinned for the default versions. If you override a runtime version, package_init verifies against the provider's published checksum file instead; set PYTHON_SHA256, NODE_SHA256, BUN_SHA256, or JAVA_SHA256 to pin a custom version yourself.

Controlling which languages install

CODEAPI_LANGUAGES=python,bun docker compose up --build

Adding a language later installs only what is missing into the existing volume. FORCE_REBUILD=true wipes and rebuilds it from scratch.

Prebuilt images

docker compose -f docker-compose.prebuilt.yml up

Pulls from ghcr.io/berry-13/codeapi-*, published by the publish-images workflow on every push to main and on version tags. Same topology, same package_init behaviour, no build step.

linux/amd64 only. On arm64 (including Apple Silicon), build from source.

The scalable stack

docker compose -f docker-compose.scalable.yml up --build

This separates the worker and sandbox into a scalable pair, mirroring how the Helm chart lays out the worker-sandbox pod. Use it when you want to exercise multi-worker behaviour (queue depth, job distribution, concurrency limits) on a single host before deploying to Kubernetes.

Its no-KVM companion is docker-compose.scalable.nokvm.yml:

docker compose -f docker-compose.scalable.yml -f docker-compose.scalable.nokvm.yml up

Local development

docker-compose.local-dev.yml adds source mounts and a faster rebuild loop for working on the service itself. docker-compose.mac.yml carries macOS-specific adjustments.

See Building and running from source for the development workflow.

Secrets in the Compose files

The local Compose files inline development values so the stack starts with no configuration:

VariableLocal defaultMust change in production
LOCAL_MODEtrueYes: this disables authentication entirely
CODEAPI_INTERNAL_SERVICE_TOKENlocaldev-internal-service-tokenYes
CODEAPI_EGRESS_GRANT_SECRETlocaldev-egress-grant-secret-change-me-32bYes: needs 32+ bytes
CODEAPI_EXECUTION_MANIFEST_PRIVATE_KEYa known test keyYes
SANDBOX_EXECUTION_MANIFEST_PUBLIC_KEYthe matching test keyYes
REDIS_PASSWORDlocaldevYes
MinIO credentialsminioadmin / minioadminYes

These are publicly known values

The manifest keypair inlined in the Compose files is the same one hardcoded in the unit tests. Anyone can read it out of the repository. It exists so docker compose up works with zero setup: it provides no security whatsoever.

Work through production hardening before running this for anyone but yourself.

Stopping and cleaning up

docker compose down            # stop, keep volumes
docker compose down -v         # also drop MinIO data
rm -rf ./data/pkgs             # force runtimes to re-download next start

On this page