This guide explains how sandbox access domains work in Cube Sandbox and how to resolve common HTTPS certificate and DNS resolution issues.
Note: TLS configuration only affects how clients reach CubeProxy.
E2B_API_URLalways points to the Cube API Server (default port3000) — a separate component from CubeProxy.
When an E2B client accesses a sandbox, the domain name is dynamically generated using the following format:
<sandbox-service-port>-<sandboxId>.<domain>
For example:
49983-1aa1fae8fb364edaa8203a7481995b4d.cube.app
Where:
sandbox-service-port: the port your sandbox application listens on (e.g.49999)sandboxId: the unique sandbox IDdomain: the base domain, defaults tocube.app, customizable via--sandbox-domain
Because the sandboxId part changes dynamically for every sandbox, the network environment where the E2B client runs must support wildcard DNS resolution — i.e., *.<domain> must resolve to the IP of the machine running CubeProxy.
The Cube one-click install script starts a CoreDNS service on the installation node that automatically handles wildcard resolution for *.cube.app. This lets you experience the full workflow on that machine without any extra DNS setup.
Note: The built-in CoreDNS is intended for local/quick-start use only — it is not suitable for production or multi-machine shared deployments.
For production deployments, use your own domain and configure a wildcard DNS record:
*.your.domain.com → <IP of the node running CubeProxy>
Then tell the Cube API Server to use that domain at startup:
# CLI flag
./cube-api --sandbox-domain your.domain.com
# Or via environment variable
export CUBE_API_SANDBOX_DOMAIN=your.domain.com
./cube-apiWith this in place, the domain field in API responses will return your.domain.com, allowing the E2B SDK to correctly construct sandbox access URLs.
CubeProxy also accepts a path-based form that routes by URL path instead of Host header. It is intended for local demos, internal ad-hoc sharing, or any environment where wildcard DNS and TLS are inconvenient to set up.
http://<cube-proxy-host>:<http-port>/sandbox/<sandbox-id>/<container-port>/<rest>?<query>
For example, a sandbox abc123 exposing port 49999 reachable through CubeProxy at 10.0.0.5:80:
http://10.0.0.5/sandbox/abc123/49999/
http://10.0.0.5/sandbox/abc123/49999/health
http://10.0.0.5/sandbox/abc123/49999/api/v1/items?limit=10
CubeProxy strips the /sandbox/<id>/<port> prefix before forwarding the request, so the upstream sandbox application sees the URI it would normally see at the root. WebSocket upgrade is supported (the proxy preserves the Upgrade / Connection headers in this location).
To help apps cooperate with the prefix, CubeProxy also:
- Sets
X-Forwarded-Prefix: /sandbox/<id>/<port>on the upstream request. - Rewrites root-relative
Locationheaders in responses back under/sandbox/<id>/<port>/...(so server-side redirects to e.g./loginkeep working). - Scopes upstream cookies sent with
Path=/toPath=/sandbox/<id>/<port>/to avoid leaking across sandboxes that share the same CubeProxy host.
When to use which:
- Host-based mode (
<port>-<id>.<domain>): preferred for SPAs and any frontend that loads assets via root-absolute paths (e.g./static/app.js). CubeProxy does not rewrite HTML bodies, so those absolute paths would otherwise miss the prefix. - Path-based mode (
/sandbox/<id>/<port>/...): preferred for HTTP APIs, simple HTML, quick previews, and one-off sharing where you do not want to manage DNS or certificates.
Both modes coexist on every CubeProxy instance and share the same Redis-backed routing metadata; no additional configuration is required to enable the path form.
CubeProxy serves both HTTPS (port 443) and HTTP (port 80) out of the box. The E2B SDK uses HTTPS by default. The one-click install pre-installs a cube.app test certificate so you can try HTTPS immediately.
To use a custom domain or production certificate, choose one of the options below:
mkcert generates a locally-trusted certificate for a custom hostname in seconds:
mkcert -install
mkcert <your-host-ip-or-domain>Set SSL_CERT_FILE so the E2B SDK trusts the generated CA:
export SSL_CERT_FILE=/root/.local/share/mkcert/rootCA.pemmkcert certificates are only trusted on machines where
mkcert -installhas been run. Not suitable for production or shared deployments.
Edit CubeProxy's nginx.conf to use your certificate and private key:
server {
listen 443 ssl;
server_name your.domain.com;
ssl_certificate /path/to/your/cert.pem;
ssl_certificate_key /path/to/your/key.pem;
}Also pass --sandbox-domain to the Cube API Server to publish the correct domain in API responses (see the "Production: Custom Domain" section above).
By default, CubeProxy listens on both HTTP and HTTPS. To disable the HTTP port entirely, remove the HTTP server block from CubeProxy's nginx.conf and drop the corresponding port mapping in docker-compose.yaml.
The E2B SDK only uses HTTPS, so disabling HTTP has no impact on SDK-based clients.
If you are experimenting with Cube in a local development environment and want to skip both wildcard DNS setup and self-signed certificate trust issues, the e2b-dev-sidecar approach is the easiest option.
It starts a lightweight local proxy that intercepts E2B SDK data-plane requests and rewrites the Host header before forwarding them to CubeProxy. This means:
- No wildcard DNS needed: no
*.cube.apprecord required on the developer machine - No certificate trust needed: the sidecar skips server certificate verification by default (
CUBE_REMOTE_PROXY_VERIFY_SSL=false)
Note: e2b-dev-sidecar is a minimal dev-only implementation and is not intended for production use.