services.md
Devbox Services
Run dev servers and other long-lived processes on a Devbox, restarted on failure and started on every boot.
A service is a command that a Devbox keeps running for you. The Devbox starts it when you create it and again every time the Devbox boots. If the command exits with an error, the Devbox restarts it. Its output is retained, so you can read the logs of a crashed dev server long after you closed the terminal that started it.
Use services for the processes your work depends on, for example:
- A dev server:
pnpm dev - Your favorite coding agent in a remote session:
amp --no-tuiorclaude --remote-control - A file watcher, a local database, or an API mock
Manage Services
A service needs a name and a command. The command runs in the Devbox's default directory unless you choose another one. Service names must be unique on a Devbox. Deleting a service stops it first: the Devbox sends SIGTERM and kills the process after 15 seconds.
CLI
# Create a service. Pass its command after --.
devbox service create my-devbox --name web -- pnpm dev
# List the services on the Devbox, with their status.
devbox service list my-devbox
# Show one service's command, directory, status, and how to reach it.
devbox service describe my-devbox web
# Stop the service and remove it permanently.
devbox service delete my-devbox web
The command runs without a shell, so wrap pipes and && in sh -c '...'. list and describe accept --output json. delete asks for confirmation; pass --force when running without a terminal. See devbox service for every option.
TS SDK
const devbox = await client.devboxes.get("my-devbox");
// Create a service. Pass the executable and its arguments separately.
await devbox.services.create({
name: "web",
command: "pnpm",
args: ["dev"],
});
// List the services on the Devbox, with their status.
for (const service of await devbox.services.list()) {
console.log(service.name, service.process?.state ?? "not started");
}
// Fetch one service by name or ID.
const web = await devbox.services.get("web");
console.log(web.process?.state, web.process?.restartCount, web.process?.lastExit);
// Stop the service and remove it permanently.
await devbox.services.delete("web");
See devbox.services for every option and field.
Dashboard
Open the Devbox in the dashboard, and press Add service in the Services section. Enter a Name and a Command, such as pnpm dev. Press Add service to create and start it.
The Services page of a Devbox lists every service with its status. Select a service to see its details and logs.
To delete a service, open the menu next to it on the Services page and select Delete.
A service is in one of these states:
| Status | Meaning |
|---|---|
starting |
The process is launching. |
running |
The process is running. |
restarting |
The process exited and is waiting to be restarted. |
failed |
The process exited and will not be restarted. |
stopping |
The service was stopped and the process is shutting down. |
stopped |
The service is stopped and will not start until you start it. |
not started |
The service has no process, for example a manual service that has not been started. |
Start and Stop Services
Start and stop a service yourself, or let its policies decide when the Devbox starts it automatically and restarts it after it exits.
Stopping a service is durable. A stopped service stays stopped across Devbox restarts until you start it again. By default, the process receives SIGTERM and is killed if it has not exited after 15 seconds.
CLI
devbox service stop my-devbox web
Add --force to kill the process immediately. Start it again with:
devbox service start my-devbox web
TS SDK
await devbox.services.stop("web");
await devbox.services.stop("web", { mode: "force" });
await devbox.services.start("web");
stop() returns once the stop is requested, so the process may still be stopping. start() fails while a service is still stopping. If the service is already running, start() returns its current process.
Dashboard
Press Stop service or Start service next to a service.
Start and Restart Policies
When a Devbox boots, it starts its services after checking out repositories and running the init script. A service that keeps failing is restarted with an increasing delay, up to about a minute between attempts. The delay resets once the service has run for a minute.
Two policies control this behavior:
- Start policy:
on-boot(default) starts the service when it is created and every time the Devbox boots.manualstarts it only when you start it explicitly. - Restart policy:
on-failure(default) restarts the service after a non-zero exit.alwaysrestarts it after any exit.neverleaves it stopped, and its status becomesfailedafter a non-zero exit.
CLI
Services created with the CLI use the defaults: they start on boot and restart on failure.
TS SDK
await devbox.services.create({
name: "worker",
command: "./scripts/worker.sh",
startPolicy: "manual",
restartPolicy: "always",
start: true,
});
start overrides the start policy at creation time: true starts the service now, and false creates it stopped. Omit it to follow startPolicy.
Dashboard
Services created in the dashboard use the defaults: they start on boot and restart on failure.
View Service Logs
The Devbox retains the output of each service run. Logs replay what has already been captured, then follow new output until that run exits. After a restart, read the logs again to see the new run.
CLI
devbox service logs my-devbox web
Add --no_follow to print the retained output and return.
Each service run is also an execution, so it appears in devbox logs list.
TS SDK
for await (const chunk of devbox.services.logs("web")) {
process.stdout.write(chunk.stdout);
process.stderr.write(chunk.stderr);
}
The loop ends when the run exits. Break out of it, or pass an abort signal, to stop reading earlier. See services.logs().
Dashboard
Select a service on the Services page. Its Logs panel streams the latest run.
Expose a Service
Expose a service's HTTP port on a shareable URL to open it in your browser. For a dev server listening on port 3000:
1. Create the service
CLI
devbox service create my-devbox --name web -- pnpm dev
TS SDK
await devbox.services.create({
name: "web",
command: "pnpm",
args: ["dev"],
});
Dashboard
Press Add service in the Services section of the Devbox, and enter the command that starts your dev server as the Command, for example pnpm dev.
2. Expose the port
CLI
devbox url expose my-devbox --port 3000 --name web
The CLI prints the devbox.so URL of the service.
TS SDK
const port = await devbox.exposedPorts.create({ name: "web", number: 3000 });
console.log(port.url);
Dashboard
Press Expose port in the Exposed URLs section of the Devbox, enter the Port and an optional Name, and press Expose port. The URL appears in the Exposed URLs section.
Next Steps
Every devbox service subcommand and option.
Define services for every Devbox created from a blueprint.
Manage services from TypeScript.