Configure with .runcode.yaml
Commit a .runcode.yaml to the root of your
repository and RunCode runs your setup commands for you. A fresh workspace, or one waking from
sleep, comes up with dependencies installed and services running. No manual steps, and it works
the same way for everyone on the repo.
Where it lives
RunCode reads the file from /home/ubuntu/workspace/.runcode.yaml,
which is the root of your cloned repository. Commit it like any other file and every workspace
built from that repo picks it up. No file? Then there are no setup steps to run, and RunCode just
skips it.
A complete example
Three optional blocks, each a plain list of shell commands run in order as the ubuntu user:
# .runcode.yaml goes at the root of your repository
onCreate:
- cd ~/workspace && pip install -r requirements.txt
- cd ~/workspace && npm ci
onStart:
- cd ~/workspace && docker compose up -d db
onRefresh:
- git -C ~/workspace fetch --all --quietThe three lifecycle blocks
onCreate runs once, everRuns a single time, right after the workspace is first built and your repo is cloned. This is the place for one-time setup: installing dependencies, building tools, seeding a database. It is only marked done if it succeeds, so a failed setup is retried on the next boot rather than left half-finished.
onStart runs every bootRuns every time the workspace powers on, including after an idle auto-stop. Use it for anything that needs to be running but does not survive a shutdown: a database, a dev server, or background services.
onRefresh runs every eventRuns on create, on start, and whenever the workspace reconciles. This is the most frequently run block, so keep it lightweight, like a quick git fetch or a status check. Save heavy or slow work for elsewhere.
Each command is its own shell
Every item in a block runs as a separate shell, so a cd on one line does not carry over to the next.
Chain dependent steps with && inside a
single item, or use absolute paths. Each block has to be a list of strings. A bare string is
rejected rather than run character by character.
# each list item is its own shell. a cd does NOT carry to the next item:
onCreate:
- cd ~/workspace/api # this cd is forgotten on the next line
- pip install -r requirements.txt # runs in the default directory!
# chain with && inside ONE item instead:
onCreate:
- cd ~/workspace/api && pip install -r requirements.txtGood to know
-
onCreate retries on failure
It is only recorded as complete once it exits cleanly, so a flaky install is retried on the next boot instead of leaving a half-provisioned box.
-
onStart runs after every wake
Because a stopped workspace shuts its processes down, onStart is your hook to bring services back each time the box powers on, idle auto-stop included.
-
Keep onRefresh cheap
It runs on every lifecycle event, so slow work here slows down routine reconnects. Reserve it for quick syncs and checks.
-
Commands run as ubuntu
They run as the ubuntu user, not root. Prefix with sudo where you genuinely need elevated privileges.
Want the bigger picture on how create, start, and refresh fire? See Workspaces & lifecycle.