Dev Preview Mode
Dev mode turns a preview environment into a long-lived hot-reload dev server instead of a compiled production image. The first push to a branch cold-starts it; every push after that just syncs your source into the running container and the framework’s file watcher reloads — so the push→preview loop drops from minutes to seconds.
How it works
- The first deploy to a branch clones the repo into a persistent checkout on the node, starts a container from a framework base image (e.g.
node:20) with your source bind-mounted, runs the install step once, and launches the framework dev server (next dev,vite,flask --debug, …). - Every later push
git fetchs and resets the checkout in place. Because the source is bind-mounted, the dev server’s watcher picks the change up and hot-reloads — no rebuild, no new container. - The container is only restarted when a lockfile (
package-lock.json,requirements.txt,go.sum, …) changes, which re-runs the install step. The dependency cache (e.g.node_modules) lives in a volume that survives restarts.
Choosing the mode
Set a project’s preview mode policy in project settings, in nexos.yaml, or via the API / MCP. Three options:
- Production (default) — every deploy compiles the production Dockerfile. Highest fidelity, slowest feedback.
- Draft-based — draft PRs run a hot-reload dev server; marking the PR ready for review flips the environment to a compiled production build (and converting back to draft flips it back to dev). The best default for branch-per-change iteration.
- Always dev — every environment runs the dev server. Fastest loop; not production parity.
In nexos.yaml:
preview:
mode: draft-based # prod | dev | draft-basedMulti-service projects
Each service decides its own path. A long-running service hot-reloads when it declares a dev_command; a service without one (say a Go API with no watch story) still compiles, even inside a dev environment — you’ll see Compiling non-dev service <name> in the logs. Multi-service projects have no per-service framework detection, so give every service you want hot-reloaded a dev_command in nexos.yaml:
containers:
- name: web
port: 3000
dev_command: npm run dev -- -p $PORT -H 0.0.0.0
- name: api
port: 4000
dev_command: npm run start:dev
- name: migrate
type: job
command: npx prisma migrate deploy
dev_watch: ["prisma/**"] # re-run only when migrations changedev_image and dev_install are optional — they fall back to the project’s detected-framework defaults (e.g. node:20 + npm install). Set them per service only when a service needs a different base image or install step.
Database migrations
Migration jobs (type: job) don’t hot-reload — they run a command and exit. In dev mode a job re-runs on a sync only when one of its dev_watch paths changed between commits (defaulting to the service’s build context). So editing a component reloads instantly without touching the database, but adding a migration re-applies it against the live database automatically.
Trade-offs
- Not production parity. Dev servers behave differently from a production build (unminified, source maps, dev-only code paths). Preview URLs in dev mode are clearly badged DEV in the dashboard — don’t treat them as a release artifact.
- Resource profile. Dev mode removes the per-push build spike but keeps a warm container running, so the cost shifts from build minutes to runtime. Lean on auto-pause to stop idle dev environments; runtime billing is settled at pause so idle time isn’t charged.
DEV_MODE_ENABLED flag. When it is off, every project runs the production build regardless of its policy. Self-hosters enable it once their node agents support dev runtimes.