Boot Sequence
The container entrypoint starts the sandbox services in this order:- Seed
/rootfrom defaults on first boot - Create
/root/workspaceand symlink/workspace - Raise inotify limits
- Start the gateway proxy (port 8888)
- Start
sshd - Run deferred install script (if present)
- Start code-server (port 8443)
- Start ttyd browser terminal (port 7681)
- Start port/resource monitor
- Snapshot installed packages for fork detection
- Mark the sandbox ready
Gateway Proxy
Each sandbox runs a gateway proxy that routes browser IDE, terminal, and application traffic through a single public endpoint.| Path | Backend | Auth | Purpose |
|---|---|---|---|
/_ide/ | code-server (8443) | Password | VS Code in browser |
/_term/ | ttyd (7681) | Password | Browser terminal |
/_port/<N>/ | Any process (N) | Password | Proxy to detected local port |
/_callback/<N>/ | Any process (N) | None | OAuth/webhook callbacks |
/_status | Gateway | None | JSON runtime status |
/_ports | Gateway | None | JSON discovered ports |
/healthz | Gateway | None | Readiness probe |
/ | App process (APP_PORT) | None | Public application URL |
/_ide/, /_term/, and /_port/ routes are password-protected via cookie session. The password is displayed in the connect panel.
Ports
| Port | Visibility | Purpose |
|---|---|---|
| 8888 | Public | Gateway endpoint |
| APP_PORT (default 8080) | Local | User application |
| 8443 | Local | code-server |
| 7681 | Local | ttyd |
| 22 | Private (port-forward only) | SSH |
Port Discovery
A background scanner checks for non-reserved TCP listeners every 10 seconds. Detected ports are available at/_ports and in the connect panel with auto-inferred labels (Vite, Next.js, Django, etc.).
The primary app port is served at the root URL (/). Additional detected ports use prefix routing (/_port/<N>/).
IDE Backends
code-server
Starts on127.0.0.1:8443 with code-server auth disabled. The gateway handles browser authentication.
Browser Terminal
ttyd starts on port 7681 with tmux for session persistence. See Terminal & tmux.SSH Server
sshd starts for desktop IDE connectivity. Interactive SSH sessions auto-attach to a persistent tmux session. The cpln sandbox connect command automates SSH access by injecting your public key, setting up port-forwarding, and launching your desktop IDE.
Persistent Workspace
/root is mounted from a persistent volumeset. Everything under /root survives container restarts and suspend/resume:
~/workspace/— repositories and working files~/.bashrc,~/.gitconfig— shell and tool config~/.config/— code-server settings, extensions~/.npm-global/— globally installed npm packages~/.local/— pip user installs
/root.
Troubleshooting
App port shows 'waiting' in sandbox status
App port shows 'waiting' in sandbox status
No process is listening on
APP_PORT. Start your app from the IDE terminal. The gateway shows a waiting page until a process binds to the port.IDE or terminal not starting
IDE or terminal not starting
Check the service logs inside the container:
Port detected but returns 502
Port detected but returns 502
The service is detected but the gateway can’t reach it. Verify the service binds to
0.0.0.0 or 127.0.0.1, not a specific interface.