Custom domain
How to set up a custom domain for Sandboxes hosted on E2B.
We will set up a GCP VM running Caddy server with Docker and Cloudflare DNS to proxy the requests to the Sandboxes.
Example: 8080-sandboxid.mydomain.com → 8080-sandboxid.e2b.app
Prerequisites
- Domain name registered and configured with Cloudflare DNS.
- Cloudflare API Token that allows you to manage DNS records.
GCP VM setup
-
Create a VM instance by running the following command:
Replace
your-project-idwith your actual project ID.gcloud compute instances create e2b-custom-domain-proxy \ --project=your-project-id \ --zone=us-west1-a \ --machine-type=n2-standard-2 \ --can-ip-forward \ --tags=http-server,https-server \ --image-project=debian-cloud \ --image-family=debian-12 \ --boot-disk-size=20GB -
After the VM is created, you can connect to it using the following command:
Replace
your-project-idwith your actual project ID.# May take a few seconds until the instance is ready to accept SSH connections gcloud compute ssh e2b-custom-domain-proxy \ --project=your-project-id \ --zone=us-west1-a
Server setup
-
Install the latest stable version of Docker:
curl -fsSL https://get.docker.com | sudo sh -
Create a Dockerfile that will be used to build the Caddy server image with Cloudflare DNS:
Dockerfile FROM caddy:builder AS builder RUN xcaddy build \ --with github.com/caddy-dns/cloudflare FROM caddy:latest COPY --from=builder /usr/bin/caddy /usr/bin/caddy -
Create a Docker Compose file that will be used to start the Caddy server:
docker-compose.yml services: caddy: build: context: . dockerfile: Dockerfile container_name: caddy-proxy restart: unless-stopped ports: - "80:80" - "443:443" - "443:443/udp" # Optional: HTTP/3 volumes: - ./Caddyfile:/etc/caddy/Caddyfile - caddy_data:/data - caddy_config:/config environment: - CLOUDFLARE_API_TOKEN=${CLOUDFLARE_API_TOKEN} networks: - caddy_network volumes: caddy_data: caddy_config: networks: caddy_network: driver: bridge -
Create a Caddyfile for proxying the requests to the Sandboxes:
Replace
*.mydomain.comwith your actual wildcard domain name.Caddyfile *.mydomain.com { # Use Cloudflare DNS for ACME challenge tls { dns cloudflare {env.CLOUDFLARE_API_TOKEN} } # Capture sandboxId for reuse # {labels.N} splits the host by "." and indexes from right to left: # e.g., for "abc123.mydomain.com": # {labels.0} = "com" (TLD) # {labels.1} = "mydomain" (domain) # {labels.2} = "abc123" (subdomain) vars sandboxId {labels.2} # Reverse proxy to corresponding e2b.app Sandbox reverse_proxy {vars.sandboxId}.e2b.app:443 { # Set the Host header to the e2b.app domain header_up Host {vars.sandboxId}.e2b.app # Forward real IP header_up X-Real-IP {remote_host} header_up X-Forwarded-For {remote_host} header_up X-Forwarded-Proto {scheme} header_up X-Forwarded-Host {host} # Use HTTPS to upstream transport http { tls tls_server_name {vars.sandboxId}.e2b.app } } # Optional: Add logging log { output file /var/log/caddy/access.log format json } } -
Create a .env file that will be used to store the Cloudflare API Token:
.env CLOUDFLARE_API_TOKEN=your-cloudflare-api-token -
Build and start the Caddy server:
docker compose build docker compose up -d
Domain setup
Log into the Cloudflare dashboard and create a new A wildcard DNS record pointing to the IP address of the GCP VM.
Replace GCP_VM_IP with the IP address of the GCP VM.
It may take a few minutes for the DNS record to propagate and for the certificate to be issued.
If you have existing AAAA (IPv6) records for this domain name, make sure they are either removed or updated to point to the GCP VM.
*.mydomain.com A GCP_VM_IPTesting the setup
We will create a new Sandbox on E2B and install a simple HTTP server in it.
-
Create a new Sandbox using E2B CLI:
e2b sandbox create base -
Install and run a simple HTTP server in the sandbox:
sudo apt install nginx sudo systemctl start nginx -
Visit the sandbox URL in your browser:
https://80-sandboxid.mydomain.com. You should see the default nginx welcome page.