Sokko Docs
Devboxes

sokko.devbox.yml

The optional file that tells Sokko how to run your repo — the command, the port, and the health check. Most repos never need it; here is what it does when you want one.

Most repos need no file at all. Sokko works out how to run yours, and if it guesses wrong your agent corrects it in one message. This page is for the case where you want the answer written down in the repo, so every devbox, every teammate and every future branch starts the same way.

That file is sokko.devbox.yml, at the root of your repository.

Committing this file is the only thing that outranks everything else Sokko knows about your repo. If a devbox is running the wrong command and you want that fixed for good, this is where you say so.

Where the run command comes from

A deploy picks its command from the first of these that exists. This order is fixed, and every deploy tells you which one it used.

OrderSourceWho wrote it
1sokko.devbox.yml (or a docker-compose.yml) in the repoyou, committed
2A run command your agent passed for this devboxyour agent, once
3The saved setup for this repo — whatever last workedSokko, from a deploy that came up healthy
4Auto-detection from the repo treenobody

Layer 3 is why the second devbox for a repo is usually right first time: when a deploy reaches a healthy running state, Sokko saves that setup for your organization and reuses it on later devboxes of the same repo. A setup that crash-looped is never saved.

The dashboard and your agent both show which layer a deploy used, along with the exact command and port. If it says detected and the app never comes up, Sokko guessed wrong — fix it with one deploy, or with this file.

The file

Two shapes, depending on whether your repo is a command or a container stack.

# sokko.devbox.yml — no Docker, no compose file needed
run: npm install && npx wrangler dev --port 8080 --ip 0.0.0.0
expose: 8080
healthcheck_path: / # optional
env: # optional, non-secret only
  NODE_ENV: development

Sokko runs run: as a shell line in your repo root, then serves whatever it finds on expose: at the preview URL.

# sokko.devbox.yml — a small override for your own compose file
compose_file: deploy/compose.yml # optional, defaults to docker-compose.yml
expose: web:3000 # which service, and which port, is the preview
healthcheck_path: /healthz # optional
env: # optional, non-secret only
  NODE_ENV: development

Your docker-compose.yml stays the source of truth. This file only says which service the preview URL points at, and where to find the compose file if it is not at the root.

Keys

KeyTypeWhat it does
runstringThe command that starts your app. Runs with sh -c in the repo root, so && and pipes work. Its presence selects run mode — no compose file is read at all. Requires expose.
exposenumber, or service:portWhere the preview comes from. In run mode, a bare port number. In compose mode, web:3000 — the service name, optionally with a port.
envmap of stringsNon-secret environment for the stack. Never put secrets here — this file is in your repo. Secrets go in the Repo secrets bundle.
healthcheck_pathstringA path Sokko fetches to decide the app is really up, like / or /healthz. Without it, Sokko only checks that something is listening on the port.
compose_filestringA repo-relative path to your compose file, when it is not docker-compose.yml at the root. Cannot be combined with run.

Every key is optional. A file with only env: and healthcheck_path: is valid — it adds those to whatever Sokko works out on its own.

Rules that will bite you

Bind 0.0.0.0, not localhost. Most dev servers listen on 127.0.0.1 by default and are invisible to everyone else. Pass the flag your framework provides — --ip 0.0.0.0, --host 0.0.0.0, -H 0.0.0.0, -b 0.0.0.0. Sokko also sets HOST and PORT for you, which many frameworks read on their own.

  • run: and compose_file: together is an error. They select different modes, so the deploy fails rather than quietly honouring one. Pick one.
  • run: wins over a docker-compose.yml sitting in the same repo. Delete the key to go back to compose.
  • expose: is required in run mode. Sokko will not guess a port for a command it cannot inspect. Without it the deploy fails immediately with PORT_DETECT_FAILED.
  • 7700, 7799 and 7800 are reserved. They belong to Sokko's own listeners inside the devbox and are rejected. Use anything else — 8080 is a good default.
  • Keep run: cheap to run twice. Your node_modules live on the devbox's disk, so npm install && … is nearly free the second time. A full production build in the run command is paid again every time the devbox restarts.
  • The command runs on the devbox's toolchain. Node (npm, pnpm, yarn, bun), Python (pip, uv), Go, and Ruby with bundler are all there. A command naming something else fails with command not found in the logs.
  • Python installs need a flag. The devbox's system Python is externally managed, so use pip install --break-system-packages -r requirements.txt. A bare pip install fails before it downloads anything.

What Sokko detects on its own

If you commit nothing, this is the ladder. The first match wins, and Sokko always picks the port itself (8080) rather than reading one out of your code.

Found at the repo rootWhat Sokko runs
docker-compose.yml, compose.yamlyour compose file, unchanged
wrangler.toml / .json / .jsoncwrangler dev --port 8080 --ip 0.0.0.0
next in package.jsonnext dev -p 8080 -H 0.0.0.0
nuxtnuxt dev --port 8080 --host 0.0.0.0
@remix-run/devremix vite:dev --port 8080 --host 0.0.0.0
astroastro dev --port 8080 --host 0.0.0.0
@sveltejs/kit or vitevite dev --port 8080 --host 0.0.0.0
a dev or start scriptthat script, with PORT and HOST set
manage.py with Djangopython manage.py runserver 0.0.0.0:8080
fastapiuvicorn <module>:app --host 0.0.0.0 --port 8080
flaskflask run --host 0.0.0.0 --port 8080
go.modgo run ., or the single ./cmd/<name>
Gemfile with bin/railsbin/rails server -b 0.0.0.0 -p 8080
a Dockerfile on its ownbuilds the image and runs it
none of the abovethe deploy fails and tells you the three ways to fix it

The package manager comes from your lockfile, never from a preference: pnpm-lock.yaml → pnpm, yarn.lock → yarn, bun.lock / bun.lockb → bun, anything else → npm. For Python, uv.lock → uv, otherwise pip. Getting this wrong is how a first deploy dies on a lockfile mismatch, so Sokko reads it rather than assuming.

Two shapes deliberately do not match, because a wrong guess costs more than no guess:

  • A monorepo root. A package.json with workspaces (or a pnpm-workspace.yaml / turbo.json beside it) and no framework of its own: its dev script starts every package on its own port and nothing lands where the preview is looking. Point run: at the app you actually want previewed.
  • A Go module with several commands, or none at the root. Sokko will not pick one for you.

Examples

run: npm install && npx wrangler dev --port 8080 --ip 0.0.0.0
expose: 8080
healthcheck_path: /

--ip 0.0.0.0 is not optional — wrangler binds 127.0.0.1 without it.

run: pnpm install && pnpm exec next dev -p 8080 -H 0.0.0.0
expose: 8080

Detected automatically for most Next repos. Write it down if you want it pinned, or if your app needs something extra before it starts.

run: pip install --break-system-packages -r requirements.txt && uvicorn app.main:app --host 0.0.0.0 --port 8080
expose: 8080
healthcheck_path: /health

Detection tries the common module layouts (main:app, app.main:app, src.main:app …). If yours is somewhere else, this file is the fix.

run: npm ci && npm run build && npm start -- --port 8080 --host 0.0.0.0
expose: 8080
healthcheck_path: /

Detection never adds a build step, because it cannot know one is needed. An app that serves nothing until it is built is exactly the case for committing this file.

Checking before you deploy

You do not have to deploy to find out what Sokko will run. Ask your agent to check the repo — it reports the command, the port, and which of the four layers above decided it, without starting anything.

If the answer is wrong, you have two fixes and they use the same words:

  • Right now, no repo change — tell your agent the run command and port. It sticks to that devbox, and once it works it becomes your organization's saved setup for the repo.
  • Permanently, for everyone — put the same values in sokko.devbox.yml and commit it. The keys are identical, so it is a copy, not a translation.

On this page