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.
| Order | Source | Who wrote it |
|---|---|---|
| 1 | sokko.devbox.yml (or a docker-compose.yml) in the repo | you, committed |
| 2 | A run command your agent passed for this devbox | your agent, once |
| 3 | The saved setup for this repo — whatever last worked | Sokko, from a deploy that came up healthy |
| 4 | Auto-detection from the repo tree | nobody |
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: developmentSokko 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: developmentYour 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
| Key | Type | What it does |
|---|---|---|
run | string | The 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. |
expose | number, or service:port | Where the preview comes from. In run mode, a bare port number. In compose mode, web:3000 — the service name, optionally with a port. |
env | map of strings | Non-secret environment for the stack. Never put secrets here — this file is in your repo. Secrets go in the Repo secrets bundle. |
healthcheck_path | string | A 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_file | string | A 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:andcompose_file:together is an error. They select different modes, so the deploy fails rather than quietly honouring one. Pick one.run:wins over adocker-compose.ymlsitting 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 withPORT_DETECT_FAILED.7700,7799and7800are reserved. They belong to Sokko's own listeners inside the devbox and are rejected. Use anything else —8080is a good default.- Keep
run:cheap to run twice. Yournode_moduleslive on the devbox's disk, sonpm 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 foundin 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 barepip installfails 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 root | What Sokko runs |
|---|---|
docker-compose.yml, compose.yaml | your compose file, unchanged |
wrangler.toml / .json / .jsonc | wrangler dev --port 8080 --ip 0.0.0.0 |
next in package.json | next dev -p 8080 -H 0.0.0.0 |
nuxt | nuxt dev --port 8080 --host 0.0.0.0 |
@remix-run/dev | remix vite:dev --port 8080 --host 0.0.0.0 |
astro | astro dev --port 8080 --host 0.0.0.0 |
@sveltejs/kit or vite | vite dev --port 8080 --host 0.0.0.0 |
a dev or start script | that script, with PORT and HOST set |
manage.py with Django | python manage.py runserver 0.0.0.0:8080 |
fastapi | uvicorn <module>:app --host 0.0.0.0 --port 8080 |
flask | flask run --host 0.0.0.0 --port 8080 |
go.mod | go run ., or the single ./cmd/<name> |
Gemfile with bin/rails | bin/rails server -b 0.0.0.0 -p 8080 |
a Dockerfile on its own | builds the image and runs it |
| none of the above | the 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.jsonwithworkspaces(or apnpm-workspace.yaml/turbo.jsonbeside it) and no framework of its own: itsdevscript starts every package on its own port and nothing lands where the preview is looking. Pointrun: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: 8080Detected 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: /healthDetection 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.ymland commit it. The keys are identical, so it is a copy, not a translation.