sandbox/ssh.md
Deno Sandbox can hand out SSH credentials so you can inspect the filesystem, tail logs, run editors, or forward ports. SSH access is available both in your terminal as a command and in the Deno Deploy Sandbox UI.
<deno-tabs group-id="sandbox-sdk"> <deno-tab value="js" label="JavaScript" default>import { Sandbox } from "@deno/sandbox";
await using sandbox = await Sandbox.create();
const { hostname, username } = await sandbox.exposeSsh();
console.log(`ssh ${username}@${hostname}`);
// keep process alive or interact via SSH until done...
await new Promise((resolve) => setTimeout(resolve, 10 * 60 * 1000));
import time
from deno_sandbox import DenoDeploy
sdk = DenoDeploy()
with sdk.sandbox.create() as sandbox:
ssh = sandbox.expose_ssh()
print(f"ssh {ssh['username']}@{ssh['hostname']}")
# keep process alive or interact via SSH until done...
time.sleep(10 * 60)
import asyncio
from deno_sandbox import AsyncDenoDeploy
sdk = AsyncDenoDeploy()
async with sdk.sandbox.create() as sandbox:
ssh = await sandbox.expose_ssh()
print(f"ssh {ssh['username']}@{ssh['hostname']}")
# keep process alive or interact via SSH until done...
await asyncio.sleep(10 * 60)
The sandbox remains reachable until the configured timeout expires. Once your
script releases its references (for example, the await using block ends) the
sandbox shuts down and the SSH endpoint disappears; you can also call
sandbox.kill() if you need to tear it down immediately.
sandbox.exposeSsh().ssh ${username}@${hostname}
You can SSH into your sandbox from the terminal using the --ssh flag when
running your script:
deno sandbox create -ssh
After creating a sandbox, you can SSH into it in the Deno Deploy web app.
Because each sandbox is already isolated, opening SSH does not compromise other projects or organizations.
The SSH tunnel closes if the sandbox shuts down. Keep it running by:
timeout: "session" (default) and keeping your managing script activetimeout: "5m" (or another duration) when creating the sandbox so it
persists after the script exits, then reconnecting later with
Sandbox.connect({ id })Cleanup is automatic when your code stops referencing the sandbox, but you can
run sandbox.kill() (or simply exit inside the SSH session) if you want to
end it on demand.
import { Sandbox } from "@deno/sandbox";
await using sandbox = await Sandbox.create({ timeout: "10m" });
// Prepare the app
await sandbox.fs.upload("./app", ".");
await sandbox.sh`deno task dev`
.noThrow(); // start server; leave running for inspection
// Get SSH details
const ssh = await sandbox.exposeSsh();
console.log(`Connect with: ssh ${ssh.username}@${ssh.hostname}`);
// Block until you're done debugging manually
await new Promise((resolve) => setTimeout(resolve, 10 * 60 * 1000));
import time
from deno_sandbox import DenoDeploy
sdk = DenoDeploy()
with sdk.sandbox.create(timeout="10m") as sandbox:
# Prepare the app
sandbox.fs.upload("./app", ".")
proc = sandbox.spawn("deno", args=["task", "dev"])
# start server; leave running for inspection
# Get SSH details
ssh = sandbox.expose_ssh()
print(f"Connect with: ssh {ssh['username']}@{ssh['hostname']}")
# Block until you're done debugging manually
time.sleep(10 * 60)
import asyncio
from deno_sandbox import AsyncDenoDeploy
sdk = AsyncDenoDeploy()
async with sdk.sandbox.create(timeout="10m") as sandbox:
# Prepare the app
await sandbox.fs.upload("./app", ".")
proc = await sandbox.spawn("deno", args=["task", "dev"])
# start server; leave running for inspection
# Get SSH details
ssh = await sandbox.expose_ssh()
print(f"Connect with: ssh {ssh['username']}@{ssh['hostname']}")
# Block until you're done debugging manually
await asyncio.sleep(10 * 60)
Use this pattern to investigate flaky builds, run interactive REPLs, or pair with teammates without promoting the code to a full Deploy app.