Skip to main content
Available for self-hosted Business plan and above
Teable Agent Runtime provides the sandbox and app runtime services used by AI Chat and App Builder. This guide deploys the complete stack on a single Linux server with Docker Compose. The deployment includes the AI sandbox engine, App Runtime, git repository service, artifact storage, and TLS gateway. Kubernetes and an additional source repository are not required because every configuration file is included below.
Self-hosted Agent Runtime is still in an early stage. This guide is intended for early adopters and will continue to evolve based on deployment feedback. The current runtime uses OpenSandbox through Teable Infra and does not use Vercel Sandbox or Vercel snapshots. For deployment assistance, contact support@teable.ai.
Use the complete stack when you need App Builder previews and deployed apps. Running only opensandbox-server does not provide the app runtime, git registry, artifact storage, or gateway required by App Builder.

Architecture

Only the Caddy gateway exposes ports 80 and 443 to the public network. All other services stay inside internal Docker networks.
ServiceDescriptionInternal port
caddyTLS termination and routing for the console, sandbox and app previews, S3, and gitPublic 80/443
opensandbox-serverAI sandbox engine in Docker mode. It uses the host docker.sock to create sandbox containers on demand.8090
infra-serviceConsole UI, Infra API, App Runtime Docker backend, and built-in app gateway8080
git-registryGit smart-http service for App Builder. It uses the same image as infra-service.8080
minio (optional)Built-in S3-compatible artifact storage. Can be replaced with external S3. See Choose Artifact Storage.9000 / 9001
minio-init (optional)One-time task that waits for MinIO to become ready and creates the artifact bucketN/A
Domain routes are derived from the root BASE_DOMAIN.
AddressPurpose
https://<BASE_DOMAIN>Console UI, Infra API, and sandbox engine API under /v1/*
https://{appId}.app.<BASE_DOMAIN>Entry point for deployed apps
https://{sandboxId}-{port}.sandbox.<BASE_DOMAIN>Sandbox port preview
https://s3.<BASE_DOMAIN>Artifact storage in built-in MinIO mode. Presigned URLs point here.
https://git.<BASE_DOMAIN>Git smart-http endpoint, optional for manual external clone

Before You Begin

Server Requirements

MinimumRecommended
vCPU48
Memory8 GB16 GB
Disk80 GB NVMe120+ GB NVMe
OSUbuntu 22.04/24.04 (x86_64)Ubuntu 22.04/24.04 (x86_64)
SoftwareDocker Engine 24+, Docker Compose v2.24+, OpenSSLDocker Engine 24+, Docker Compose v2.24+, OpenSSL
Capacity notes: each active build session runs one sandbox container with a limit of 2 vCPU and 4 GiB. Each deployed app also has a limit of 2 vCPU and 4 GiB, though typical usage is only a few hundred MB. The base services use about 1 to 1.5 GiB of memory. Disk usage mainly comes from container images, about 15 to 20 GB after warm-up, plus writable layers for sandboxes and apps. Monitor free disk space.

DNS and Firewall

Add 4 A records at your DNS provider. All records must point to the server public IP. A wildcard certificate only covers one subdomain level, so all 4 records are required.
If the domain is hosted on Cloudflare, set these 4 records to DNS only (gray cloud), not Proxied (orange cloud).
Only allow inbound 22 (SSH), 80, and 443 in the firewall. Do not expose other ports.

Container Images

This deployment uses GHCR + Docker Hub by default. All images are public and do not require docker login. For Teable images, <tag> is not a fixed value. Open each corresponding GHCR package page and use the release tag shown in that package page’s Installation command. Confirm the tag for each image separately. Do not assume the tags are the same across images.

Images Managed by Docker Compose

These images are pulled and started by docker compose up.
PurposeImage templatePackage page
Console, Infra API, and App Runtime. infra-service and git-registry use the same image. The latter only uses a different startup entry point.ghcr.io/teableio/teable-infra-service:<tag>GHCR
AI sandbox engine, OpenSandbox in Docker runtime mode, Teable buildghcr.io/teableio/opensandbox-server:<tag>GHCR
TLS edge gateway. The official image is used for static certificate mode. Cloudflare mode requires a local build, see Choose a TLS Mode.caddy:2.9.1Docker Hub
Built-in artifact storage, only used in built-in MinIO mode. Pinning by digest is recommended for production.minio/minio:latestDocker Hub
One-time bucket creation tool, only used in built-in MinIO modeminio/mc:latestDocker Hub

Runtime Images

These images are not started by compose directly. The services use the host docker.sock to create containers from them on demand. They are public images and can be pulled anonymously by the Docker daemon. Pre-pulling them as described in Pre-pull Runtime Images is recommended to avoid first-use latency when creating the first sandbox or deploying the first app.
PurposeImage templatePackage page
Sandbox base image. Each AI build session runs inside this image.ghcr.io/teableio/teable-sandbox-agent:<tag>GHCR
App runtime base image. Each deployed app container uses this image. Apps cannot be deployed if this is not configured.ghcr.io/teableio/teable-app-runtime:<tag>GHCR
Sandbox execution agent execd, injected by the engine into each sandbox containerghcr.io/teableio/opensandbox-execd:v1.0.19-fix-1064GHCR
Sandbox outbound network sidecar, egress in DNS mode, created by the engine for each sandbox as neededopensandbox/egress:v1.0.12Docker Hub
Use the Teable-built fixed version of execd shown above, opensandbox-execd:v1.0.19-fix-1064. Do not replace it with the upstream opensandbox/execd image.

Choose Artifact Storage

ModeConfigurationNotes
Built-in MinIO (default)Leave S3_ENDPOINT empty in .env, keep COMPOSE_PROFILES=minioMinIO starts automatically and the bucket is created. Presigned URLs use https://s3.<BASE_DOMAIN>.
External S3Set S3_ENDPOINT to the provider URL and set COMPOSE_PROFILES= to emptyBuilt-in MinIO no longer starts. S3_ACCESS_KEY, S3_SECRET_KEY, and S3_BUCKET must use provider-issued values. The bucket must already exist. If the provider only supports virtual-host style, set S3_FORCE_PATH_STYLE=false.

Create the Deployment Files

Deployment Directory

Create a deployment directory on the server. This guide uses teable-runtime/ as the example directory. The Configuration Files section contains the full contents of the first four files.
The files containing secrets are .env and compose.override.yaml. Do not share them externally or commit them to a repository.

Configuration Files

.env

.env

compose.yaml

Copy this file as is. All environment-specific values are loaded from .env.
compose.yaml

Caddyfile

The file is written for static certificate mode by default. For cloudflare mode, make the two changes described in the file header and under Choose a TLS Mode.
Caddyfile

opensandbox.toml

Copy this file as is.
opensandbox.toml

Deploy Agent Runtime

Configure .env and Generate Secrets

Edit the .env file from Configuration Files. Required items:
  • BASE_DOMAIN / INFRA_HOST: your root domain. INFRA_HOST is usually the same as BASE_DOMAIN.
  • Images: fill the image list under Container Images. For each Teable image, copy the <tag> from the Installation command on that image’s GHCR package page.
  • Secrets: generate and fill them with the commands below.

Choose a TLS Mode

ModePreparationCertificate renewal
static (self-provided certificate, default)Put fullchain.pem and privkey.pem into certs/. The certificate must be a single multi-SAN certificate covering <BASE>, *.<BASE>, *.app.<BASE>, and *.sandbox.<BASE>, and the private key must match it. Wildcards cover only one level.Manual. Replace files in certs/, then run docker compose exec caddy caddy reload -c /etc/caddy/Caddyfile.
cloudflare (DNS-01 automatic issuance)DNS must be hosted on Cloudflare. Prepare an API token with Zone:Read + DNS:Edit permissions.Fully automatic through Caddy
static mode: the configuration files above are already written for this mode. Put the certificate files in place. No other change is needed. Use the following commands to check certificate SAN coverage and whether the certificate matches the private key:
cloudflare mode requires 4 changes:
  1. The official Caddy image does not include the DNS plugin. Save the following content as Dockerfile.caddy and build it locally:
    Dockerfile.caddy
  2. In .env, set CADDY_IMAGE=teable-caddy-cloudflare:2.9.1, and fill ACME_EMAIL and CLOUDFLARE_API_TOKEN.
  3. In Caddyfile, follow the file header and uncomment the global block, including email and acme_dns cloudflare.
  4. In Caddyfile, delete the tls /certs/... line inside the (site_tls) snippet. Certificates will be managed automatically by ACME.
In Cloudflare mode, the caddy-data volume must be persistent. It stores certificates and the ACME account. If it is lost, Caddy will request certificates again after rebuilds, which can trigger Let’s Encrypt rate limits.

Generate the Git Service Signing Key

The git service uses an Ed25519 key pair to sign and verify access tokens. Multi-line PEM values cannot be stored cleanly in .env, so they are injected through compose.override.yaml, which Docker Compose loads automatically. Run this in the deployment directory:
The generated compose.override.yaml will have this structure. The PEM content is your generated key:
compose.override.yaml
To rotate the key, run this section again.
If openssl genpkey reports Algorithm ed25519 not found, for example on macOS with LibreSSL, use Docker to generate the key pair, then run the same assembly command above:

Create the Shared Workspace Volume

The Agent shared workspace uses an external volume. Since compose declares it as external, compose will not create or delete it automatically.

Pre-pull Runtime Images

All images are public. docker login is not required.
The execd and egress image addresses must exactly match the values configured in opensandbox.toml.

Start the Services

Verify the Deployment

Check Service Health

Console UI: open https://<BASE_DOMAIN> in a browser, or the host configured in INFRA_HOST. Log in with api-key. The key is the OPENSANDBOX_API_KEY value in .env.

Connect Teable

Add these environment variables to the Teable deployment:
Use the same value for TEABLE_INFRA_API_KEY as OPENSANDBOX_API_KEY in the Agent Runtime .env file. The SANDBOX_OPENSANDBOX_IMAGE value must also match the sandbox image configured for Agent Runtime. TEABLE_INFRA_API_URL must point to the Teable Infra root URL without a path. Restart Teable after updating the variables.

Troubleshooting

ProblemWhat to check
Teable reports that Agent Runtime is not configuredConfirm all four Teable environment variables above are set, then restart Teable.
Sandbox or app previews return DNS, TLS, or 404 errorsConfirm all four DNS records point to the server and the certificate covers every required hostname.
The first sandbox or app deployment is slowPre-pull all runtime images before the first use.
A service is unhealthyRun docker compose ps, then inspect the affected service with docker compose logs <service>.
If you need deployment assistance, contact support@teable.ai and include the output of docker compose ps and the relevant service logs.

Operations

View Logs and Manage Services

Upgrade

Update the image tags in .env, then run docker compose pull && docker compose up -d. After updating the sandbox or app base image, or execd / egress, pre-pull the images again as described in Pre-pull Runtime Images.

Back Up Data

Back up these volumes regularly, especially minio-data and caddy-data.
VolumeContent
opensandbox-stateSandbox engine state, SQLite
infra-stateApp Runtime state and drafts
git-registry-dataGit repository data
minio-dataArtifact files, built-in MinIO mode
teable-agent-juicefsAgent shared workspace, external volume created during deployment
caddy-data / caddy-configTLS certificates, ACME account, and Caddy configuration
docker compose down -v deletes data volumes too, including artifacts, Git repositories, and certificates. Use it carefully.

Security and Limitations

Security

  • The only files containing secrets are .env and compose.override.yaml. Do not commit them to a repository or share them externally.
  • The whole stack uses one shared OPENSANDBOX_API_KEY. If you need separate permissions, replace the corresponding environment variables for each service separately.
  • docker.sock is mounted into opensandbox-server and infra-service. This is required for the Docker backend and is equivalent to host root access. Deploy only on a dedicated and trusted host.
  • The only public entry point is Caddy on ports 80 and 443. The MinIO console on 9001 is not exposed. Use an SSH tunnel if access is needed.
  • Sandboxes share the host kernel. This is not a strong multi-tenant isolation boundary. For public multi-tenant scenarios, configure a stronger isolation runtime for the sandbox engine, such as gVisor or Kata.

Capability Boundaries

Available: full sandbox engine functionality; the main app lifecycle, including create, activate, gateway access, delete, dashboard, logs, and S3 artifacts; git push and pull; console api-key login and Infra API; file browser and S3-compatible API. Unavailable or limited due to Docker mode tradeoffs: app host-prefix rename returns 501; scale-to-zero idle scaling is a no-op; engine key rotation and server rolling upgrade are not supported; Kubernetes observability pages in the console are empty, which is expected.
Last modified on July 14, 2026