Instant use sandboxes for coding agents on Cloudflare with Cloudsail (Alpha). It runs on Cloudflare Workers, Durable Objects, Containers, and Sandboxes, and gives you a local CLI that opens an isolated remote computer for each project, PR, task, or experiment.
Use it when you want to run Codex, tests, package installs, git commands, and dev servers away from your laptop while keeping each workspace separated.
Features
- Instant Sandboxes: Create as many isolated project sandboxes as you need, then destroy them when done.
- Secure by Default: GitHub and API credentials live in the Worker instead of being exposed to compromised containers.
- Controlled Egress: Access GitHub, OpenAI/ChatGPT, and package registries by default; add docs hosts with
cs allow. - GitHub Integration: Start with a GitHub Repo or PR URL, inspect diffs, commit, push, and open PRs.
Requirements
- Node 23+
- A Cloudflare account with Workers, Durable Objects, Containers, and Sandboxes enabled
- Docker Desktop, or another Docker-compatible daemon, for
cs deploy - Git
For Codex, either use ChatGPT subscription auth inside the sandbox or configure OPENAI_API_KEY as a Worker secret. For GitHub, a fine-grained token works for alpha testing; a GitHub App installation is the better long-term credential.
Install
npm install -g cloudsail
Log in to Cloudflare if you have Wrangler on your PATH:
wrangler login
If wrangler is not already on your PATH, skip that command. The Cloudsail package includes Wrangler, and cs setup will open Cloudflare login with the packaged copy if needed.
Deploy Your Cloudsail
Run setup once:
cs setup
cs setup creates ~/.config/cloudsail/config.json, writes the deploy config to ~/.config/cloudsail/deploy/wrangler.jsonc, generates a local auth token, and stores that token as the Worker secret CLOUDSAIL_AUTH_TOKEN.
Set optional credentials. If the variable already exists in your environment, Cloudsail passes it to Wrangler; otherwise Wrangler prompts securely:
cs secret set GITHUB_TOKEN
cs secret set OPENAI_API_KEY
For GitHub App auth:
cs secret set GITHUB_APP_ID
cs secret set GITHUB_APP_INSTALLATION_ID
GITHUB_APP_PRIVATE_KEY="$(cat private-key.pem)" cs secret set GITHUB_APP_PRIVATE_KEY
Deploy the Worker and container image:
cs deploy
cs deploy runs Wrangler against the packaged Worker and Dockerfile. You do not need to clone the Cloudsail repo. After deploy, it saves the deployed Worker URL into ~/.config/cloudsail/config.json.
Check the setup:
cs doctor
Useful setup commands:
cs config show
cs config path
cs config deploy-path
cs secret list
cs deploy --dry-run
Use a different Worker name:
cs setup --name my-cloudsail
cs deploy --name my-cloudsail
First Sandbox
Create an empty sandbox:
cs create my-task --type standard-2
cs shell my-task
Seed a sandbox from a GitHub repo:
cs gh https://github.com/owner/repo my-task
cs shell my-task
Seed from a pull request:
cs gh https://github.com/owner/repo/pull/123 fix-123
cs shell fix-123
Inside cs shell, commands run in the remote sandbox:
pnpm install
pnpm test
codex
Jump straight into Codex:
cs codex my-task
Run a one-off command:
cs run my-task -- 'pwd; git status --short; pnpm test'
Testing Web Apps
Start a dev server in the sandbox and expose it:
cs dev my-task --port 5173 -- pnpm dev --host 0.0.0.0
cs ports my-task
cs open my-task 5173
You can also run the dev server manually inside cs shell, then expose the port:
pnpm dev --host 0.0.0.0
cs expose my-task 5173
Production preview URLs need a Cloudflare route that can receive the generated preview hostnames. For serious browser testing, configure CLOUDSAIL_PREVIEW_HOST in ~/.config/cloudsail/deploy/wrangler.jsonc or in the Cloudflare dashboard before deploying.
Preview URLs are authenticated. Open them with cs open, cs dev, or cs expose; the CLI mints a short-lived browser ticket and the Worker stores it as an HTTP-only cookie. Raw exposed URLs return 401 unless the request includes CLOUDSAIL_AUTH_TOKEN bearer auth.
Credentials
Cloudsail keeps Worker-owned credentials outside the remote computer. The sandbox receives a harmless placeholder OPENAI_API_KEY so API-key CLIs can detect that auth exists. When an approved HTTP or HTTPS request leaves the sandbox, the Worker injects the real credential at the edge.
api.openai.com: Worker injectsOPENAI_API_KEY.chatgpt.com: Codex ChatGPT subscription traffic is allowed; Cloudsail does not inject subscription credentials.github.comandapi.github.com: Worker injects GitHub auth only for the project's repo.- The container cannot read the real token from env, files, process args, or shell history.
- Terminal WebSockets use short-lived one-time tickets.
- Public internet is blocked by default except for the configured HTTP/S allowlist.
Inside cs shell, echo "$OPENAI_API_KEY" prints the placeholder, not your real key. git fetch, git push, and OpenAI API calls still work through Worker-side injection.
Egress
Sandboxes start with the hosts needed for normal development: GitHub, OpenAI, ChatGPT, npm registries, and common GitHub asset hosts.
Add docs or research hosts per project:
cs egress my-task
cs allow my-task viteplus.dev
cs allow my-task docs.astro.build
cs disallow my-task viteplus.dev
Project-added hosts are read-only. GET, HEAD, and OPTIONS are allowed; mutating requests are blocked.
Git Workflow
Use normal git inside the sandbox:
git status
git add -A
git commit -m "Build feature"
git push origin HEAD:cloudsail/my-feature
Cloudsail also includes optional helpers:
cs diff my-task
cs changes my-task
cs commit my-task "Build feature"
cs push my-task cloudsail/my-feature
cs pr my-task "Build feature"
cs changes --json exposes commit and file before/after data for tools such as codiff.
Lifecycle and Cost
Cloudsail defaults to CLOUDSAIL_SANDBOX_SLEEP_AFTER=3h. A sandbox can stay warm during active work, then Cloudflare can shut it down after roughly three idle hours.
Live terminals and dev servers stop when the sandbox sleeps. Durable state should be in Git commits, pushed branches, or checkpoints. Cloudsail is not a durable VM unless you checkpoint or push your work.
Change keepalive per sandbox:
cs keepalive my-task 3h
cs keepalive my-task 24h
cs keepalive my-task 7d
cs keepalive my-task forever
cs keepalive my-task off
forever keeps the sandbox alive until you destroy it:
cs destroy my-task
Approximate idle live cost for the default standard-2 container:
3h: about$0.17per sandbox24h: about$1.37per sandbox7d: about$9.58per sandbox
CPU usage, Workers, Durable Objects, logs, egress, and included monthly usage can change the final bill.
Project Config
Cloudsail stores user config at:
~/.config/cloudsail/config.json
Repo-local defaults can live in .cloudsail.json:
cs init
Environment variables override stored config for one command:
CLOUDSAIL_URL=https://your-worker.workers.dev CLOUDSAIL_AUTH_TOKEN=... cs doctor
Comments