惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

The GitHub Blog
The GitHub Blog
Jina AI
Jina AI
月光博客
月光博客
博客园 - Franky
小众软件
小众软件
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
V
Visual Studio Blog
有赞技术团队
有赞技术团队
V
V2EX
IT之家
IT之家
阮一峰的网络日志
阮一峰的网络日志
Stack Overflow Blog
Stack Overflow Blog
H
Help Net Security
Apple Machine Learning Research
Apple Machine Learning Research
腾讯CDC
D
DataBreaches.Net
Hugging Face - Blog
Hugging Face - Blog
Martin Fowler
Martin Fowler
罗磊的独立博客
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
WordPress大学
WordPress大学
C
Check Point Blog
Microsoft Azure Blog
Microsoft Azure Blog
Microsoft Security Blog
Microsoft Security Blog

Railway Blog

Where Railway is, and where it's going (Summer 2026) PaaS vs IaaS vs SaaS: What Each Means and Who Should Pick What in 2026 The Best Continuous Deployment Tools in 2026 The Best PaaS for Multi-Region Deployments in 2026 The Best Platforms for Monorepo Deployments in 2026 Compliance Isn't a Feature, It's a Posture What is BYOC (Bring Your Own Cloud)? A Developer's Guide for 2026 The Best Managed Kubernetes Hosting in 2026 The Best Container Registries in 2026 The Vanilla Cloud Tax: What Rolling Your Own on AWS Actually Costs What is a PaaS? A Developer's Guide for 2026 The Best Cloud Observability and Logging Tools in 2026 The Best PostgreSQL Hosting for Developers in 2026 The Best Multi-Region Hosting Platforms in 2026 Incident Report: May 19, 2026- GCP Account Suspension Counting to 3 with a new builder processing 50M+ monthly builds Railway iOS preview now available via TestFlight Kill your onboarding: selling to 10,000+ new users a day Your AI wants to nuke your database. Guardrails fix that. Better Rails for Agents: A New Remote MCP and Railway Agent in the CLI Moving Railway's Frontend Off Next.js One command deploys, there's a Stripe APP for that From registrar to deployed: buying a domain inside Railway A letter to open source builders who deserve more Networking is a black box, we used eBPF to open it Heroku Walked So Railway Can Run Security Features Your Security Team Will Love Railway Runs Open Source, Now We're Funding It Railway raises $100M Series B to unburden the builders Deploy autoscaling services, AI Workflow automation, and LLM APIs Without Kubernetes
Claude Code, OpenAI Codex, OpenCode and Pi are now availa...
Cody De Arkland · 2026-06-24 · via Railway Blog

Avatar of Cody De Arkland

Cody De Arkland

Agents in the Sandbox

Railway sandboxes now include Claude Code, Codex, OpenCode, and Pi in their default image. If you haven't enabled them yet, Sandboxes are available through Priority Boarding. It turns out, wild as it may seem, people really like using sandboxes for agent workloads.

You should not have to spend the first few minutes of every sandbox session figuring out how to get the same agent harness installed that you ran in slightly different ways 20 times before. Unnecessary friction is... unnecessary. We want to make it easy to quickly stand up agents that you can use right alongside the applications and infrastructure you are already using in Railway. Fire up the agent, get your configurations in place, checkpoint, and loop.

For now, you still have to either pass iny our agents configuration information, or API's key's using something like --variable and Global Variables; but we've got plans. Keep an eye on this space!

More than a shell

The most obvious angle with the sandbox story we all tell is "give the agent a computer." It's useful and translates well, but we're a lot more interested in how we can give your sandboxes and their agents the entirety of Railway's infrastructure at their disposal. What if these sandboxes could immediately spin up the databases they need? Or functions to help test their functionality against?

A sandbox on Railway shouldn't just be a shell floating off to the side. Because it lives alongside the rest of your Railway environment, it can join the same network and talk to the services alongside it. Pass --private-network when you create a sandbox and it ends up on your environment's private network.

This means that not only can sandboxes do the typical "run untrusted code" things, but they can also test code against the same types of infrastructure that they will eventually use: Postgres, Redis, internal services, variables, whatever is in the project.

How do you hold the Sandbox?

The loop we most commonly see users adopt looks something like:

  1. Create a reusable base template for the work (railway sandbox template build)
  2. Start a sandbox from that base (railway sandbox create --template)
  3. Configure it for the task: sign into agents, write guidance files, install packages, seed variables
  4. Checkpoint the configured state (railway sandbox checkpoint create)
  5. Create sandboxes from that checkpoint, or fork the current sandbox as the work branches (railway sandbox create --checkpoint / railway sandbox fork --variable)

We shipped checkpoints and port forwarding in the CLI recently. Checkpoints let you snapshot the current state of the storage for the sandbox, and forward lets you connect to services running within the sandbox from your local system.

The end state of this workflow gives you a working configuration that can be forked into as many sandboxes as you need, very fast. Each new run is just another create, and you can even connect to the services running within them if needed.

The SDK loop

So far, all the examples we've given have been around the CLI, but if you're integrating sandboxes into your application - the TypeScript SDK is the primary programmatic interface. The SDK is open source on GitHub. The quick version looks like this:

import { Sandbox } from "railway";

const sandbox = await Sandbox.create();

const result = await sandbox.exec("git --version");
console.log(result.stdout);

await sandbox.destroy();

Sandbox.create() gives you a running sandbox, ready to exec against.

Where it gets more interesting is when you stop treating each sandbox like a one-off machine and start treating it like a branchable work environment.

For example, Repo Review Agent is an app where a user pastes in a GitHub repo, and the agents check over different application configurations. The app first prepares the repo once by cloning it, installs dependencies, checkpoints it, then creates new sandboxes for each agent runs: one for tests, one for architecture, one for security, one for product polish.

Repo Review Agent
Repo Review Agent

The useful loop is: boot a sandbox from a known base, clone the repo, install dependencies, run a verification step, checkpoint the prepared workspace, then create one sandbox per agent from that checkpoint. When the run is over, collect the results and destroy the temporary sandboxes.

import { Sandbox } from "railway";

// git, Node, npm, and the four agents already ship in the default image,
// so there is nothing to install up front — just create and get to work.
const sandbox = await Sandbox.create({
  idleTimeoutMinutes: 30,
  env: {
    RAILWAY_API_TOKEN: process.env.RAILWAY_API_TOKEN!,
    DATABASE_URL: "${{Postgres.DATABASE_URL}}",
  },
  networkIsolation: "PRIVATE",
});

await sandbox.exec(
  "bash -lc 'git clone https://github.com/codyde/repo-review-agent /root/workspace'",
);

await sandbox.files.write(
  "/root/workspace/AGENTS.md",
  [
    "# sandbox guidance",
    "Work in /root/workspace.",
    "Write important results to files before the turn ends.",
  ].join("\n"),
);

const install = await sandbox.exec("bash -lc 'npm ci'", {
  cwd: "/root/workspace",
});

if (install.exitCode !== 0) {
  console.error(install.stderr);
}

const check = await sandbox.exec("bash -lc 'npm run build'", {
  cwd: "/root/workspace",
  timeoutSec: 120,
});

if (check.exitCode !== 0) {
  console.error(check.stderr);
}

await sandbox.checkpoint("repo-review-agent");

The ${{Postgres.DATABASE_URL}} syntax resolves Railway variable references when the sandbox is created. networkIsolation: "PRIVATE" joins the sandbox to your environment's private network. The sandbox.files.write call writes an AGENTS.md guidance file directly to the workspace.

The default image carries the toolchain and the agents, so the live sandbox just clones, installs, and verifies. The checkpoint captures that prepared state — every later run boots straight into it instead of repeating the setup.

Sandboxes use mise for the default toolchain, so for non-interactive exec calls I like to run through bash -lc. That gives you the same configured environment the sandbox image expects.

Later, from another process, another machine, or another step in your workflow:

import { Sandbox } from "railway";

const sandbox = await Sandbox.create("repo-review-agent", {
  env: {
    ANTHROPIC_API_KEY: process.env.ANTHROPIC_API_KEY!,
  },
});

const agent = sandbox.exec(
  'bash -lc \'claude -p "review the architecture of src/lib/review.server.ts and propose improvements"\'',
  {
    cwd: "/root/workspace",
    onStdout: (chunk) => process.stdout.write(chunk),
    onStderr: (chunk) => process.stdout.write(chunk),
  },
);

const sessionName = await agent.sessionName;
await agent.detach();

console.log(`Agent is running in session ${sessionName}`);

Long-running commands keep running in the sandbox even if your client disconnects. You get a durable session name back, and can reattach later:

const sandbox = await Sandbox.connect(process.env.SANDBOX_ID!);

await sandbox.exec(
  { sessionName: process.env.AGENT_SESSION! },
  {
    resumeFromLastRead: true,
    onStdout: (chunk) => process.stdout.write(chunk),
  },
);

For agent workflows, this is one of the most useful features. You are not forced to keep one local process alive forever just to keep the work going. The sandbox is the place where the work is happening. If you have a checkpoint, getting back into that state is one call away.

Fork when the work branches

Checkpoints are great for reusable bases. Forks are great when the work branches from something already running.

Using the example of our Repo Review Agent, we take a fresh checkpoint after our application is cloned, dependencies are installed, and everything is configured. This lets us fire off the 4 subagents that do the different application review flows.

Subagent runs in Repo Review Agent
Subagent runs in Repo Review Agent

Install dependencies once. Clone the filesystem. Try two approaches independently.

const base = await Sandbox.create("repo-review-agent");

const bugReview = await base.fork();
const securityReview = await base.fork();

await Promise.all([
  bugReview.exec(
    "bash -lc \"codex exec 'find likely bugs in src/lib/review.server.ts, then run npm run build'\"",
    { cwd: "/root/workspace" },
  ),
  securityReview.exec(
    "bash -lc \"opencode run 'audit the sandbox exec calls for command injection'\"",
    { cwd: "/root/workspace" },
  ),
]);

In our example, we create new from the checkpoint, but forks are an option here too. The forks boot fresh from the same disk state of the running system that we took our checkpoint on originally. Files are preserved. Running processes are not. That is usually exactly what you want: copy the workbench, not the half-running experiment. Pick up where we left off.

The CLI loop

For a lot of work, you do not need to write code around the sandbox at all. The Railway CLI gives you the same basic shape from your terminal. See the railway sandbox reference for every subcommand.

The default image already ships git, Node, npm, and the four agents, so for an app like this there is nothing to pre-install — create a sandbox directly. (Reach for railway sandbox template build when you need something the image does not include.)

railway sandbox create --private-network

Run the setup:

railway sandbox exec -- bash -lc 'git clone https://github.com/codyde/repo-review-agent /root/workspace'
railway sandbox exec -- bash -lc 'cd /root/workspace && npm ci'

Checkpoint the good state:

railway sandbox checkpoint create repo-review-agent

Spin up another sandbox from it:

railway sandbox create --checkpoint repo-review-agent

Now run the agent:

railway sandbox exec -- bash -lc 'codex exec "review the repo for likely bugs and explain what you would change"'

Or forward a dev server back to your machine with railway sandbox forward:

railway sandbox exec --detach -- bash -lc 'cd /root/workspace && npm run dev'
railway sandbox forward 8080

The sandbox sets PORT=8080, and the app binds it, so forward 8080 to reach the dev server on localhost:8080.

The CLI keeps an active sandbox for the current session, so most of the time you are not carrying IDs around. Create it, exec into it, checkpoint it, fork it, destroy it.

railway sandbox fork
railway sandbox exec -- bash -lc 'cd /root/workspace && npm run build'
railway sandbox destroy

Less ceremony. More loops.

Templates vs checkpoints vs forks

They look similar, but the differences are worth talking through.

Templates are built from ordered shell instructions. Use them for repeatable bases: install common packages, set up language tooling, prewarm a known environment. Railway content-addresses and caches them, so rebuilding the same template is cheap.

Checkpoints capture the disk of a running sandbox into a named snapshot stored server-side in the environment. Use them after expensive live setup: cloned repo, installed deps, generated assets, migrated fixtures. You can destroy the original sandbox and still create from the checkpoint later.

Forks clone a running sandbox into another running sandbox. Use them when the work branches right now: compare two fixes, run parallel agent attempts, split one reproduction into multiple experiments.

The combination of these gives agents a much better loop:

template -> sandbox -> configure -> checkpoint -> create/fork -> verify -> destroy

The agent does not need to rebuild the world every time. It can carry forward the useful state and throw away the rest. This loop becomes even more powerful when you look at how you can parallelize the workloads. Our earlier example showed the 4 agent moving through the review processes.

Agnet results in parallel
Agnet results in parallel

We're able to capture the results, have the agents return them, and destroy themselves after. If we needed to run the agents again, it would be as simple as booting up the checkpoint again and moving forward.

Sandbox UI in railway
Sandbox UI in railway

Why bundle the agents?

Setup friction compounds fast. We're here to beat that back.

If you create one sandbox, installing your preferred harness by hand is annoying. If you create a lot of them, or fork across multiple attempts, it becomes the thing that slows down the loop for no good reason.

Claude Code, Codex, OpenCode, and Pi being available by default means the sandbox is much closer to the work at creation time. Start the environment, run the agent, inspect the result, checkpoint what matters, fork when the work needs to branch.

These four give a wide range of model availability and high developer experience. Pair them with Railway Agent Skills on your local harness so the agent knows how to drive sandboxes, checkpoints, and forks from your editor too.

This is the direction we want Railway sandboxes to keep moving: less bootstrap, more useful work. Faster loops, happening right next to all the infrastructure you already have.

Agents are better when they have a computer, but agents are incredible when they have access to all your infrastructure.

Further reading

Happy shipping.

-- Cody