NexosNexos

nexos.yaml

One file at the root of your repo configures your entire preview environment — the Dockerfile, the port, the services, the migrations, the secrets. Nexos reads it on every push and applies it before the build starts. Every field is optional.

Let an AI generate it for you

Open your AI assistant inside your repo and paste this link: nexos.rs/docs/nexos-yaml/ai. That page is a self-contained spec written for AI agents — it tells them exactly how to detect your stack, write your nexos.yaml, and create a Dockerfile.nexos if your repo doesn't have a Dockerfile that works for preview environments. No setup, no back-and-forth.

Where to put it

You have two options. Pick whichever fits your workflow:

  1. Commit it to your repo as nexos.yaml at the root. Nexos fetches it from each pushed commit and applies it before building. Branches can have different configs — useful for testing a setting change in isolation.
  2. Paste it in the dashboard. Open Project → Settings → YAML, paste, click Apply. Useful when you want to try a config without a commit, or to bulk-import env vars and services.

If both exist, the committed file wins for fields it sets. Anything it omits keeps the dashboard value. Treat the repo file as the source of truth for everything you want version-controlled.

Full example

Every field below is optional. Drop in just the ones you care about.

# nexos.yaml
name: my-app

build:
  dockerfile: ./Dockerfile        # or ./Dockerfile.nexos
  context: .
  args:
    NODE_VERSION: "20"

app:
  port: 3000                       # injected as $PORT
  cpu: 1                           # cores
  memory: 512                      # MB

buildResources:
  cpu: 2
  memory: 2048
  timeout: 600                     # seconds

services:
  postgres: true                   # shorthand: enabled with defaults
  redis:
    enabled: true
    version: "7"
  mongodb: false                   # explicitly disabled

hooks:
  on_deploy: npx prisma migrate deploy
  on_new: node scripts/seed-admin.js

env:
  NODE_ENV: production
  LOG_LEVEL: info

containers:
  - name: worker
    dockerfile: ./worker/Dockerfile
    cpu: 0.5
    memory: 256
    command: node worker.js
    depends_on: [api]
    env:
      QUEUE_NAME: jobs

  - name: api
    dockerfile: ./api/Dockerfile
    port: 3001
    public: true                   # gets its own preview subdomain

Minimal example

For a Node app with Postgres, this is all you need:

# nexos.yaml — minimum viable
app:
  port: 3000
services:
  postgres: true

Field reference

name

Project display name. Used in the dashboard and in preview URLs: {branch}-{name}.nexos.rs.

build

  • dockerfile — path to the Dockerfile. Default ./Dockerfile. Use ./Dockerfile.nexos if you want a Nexos-specific build alongside an existing Dockerfile.
  • context — build context directory. Default ..
  • args — key/value pairs passed as --build-arg. Stored in plaintext; not for secrets.

app

The main container — what users hit when they open the preview URL.

  • port — port your app listens on. Also injected as $PORT so frameworks pick it up automatically.
  • cpu — CPU cores (e.g. 0.5, 1, 2). Default 1.
  • memory — RAM in MB. Default 512.

buildResources

Limits applied during the image build, separate from runtime limits.

  • cpu — cores for the build. Default 2.
  • memory — RAM in MB during the build. Default 2048.
  • timeout — max build duration in seconds. Default 600 (10 minutes). Hung builds get killed.

services

Managed addons that get provisioned alongside your app. Each environment gets its own copy — push a new branch, get a fresh database. Use the boolean shorthand to enable with defaults, or an object to pin a version or storage size.

ServiceVersionsInjected env var
postgres14, 15, 16DATABASE_URL
redis6, 7REDIS_URL
mongodb5, 6, 7MONGODB_URL
elasticsearch7.x, 8.xELASTICSEARCH_URL
minio (S3-compatible)latestS3_ENDPOINT, S3_ACCESS_KEY, S3_SECRET_KEY, S3_BUCKET
mailhog (SMTP capture)latestSMTP_HOST, SMTP_PORT

Object form fields:

  • enabled — defaults to true if the key is present. Set false to disable.
  • version — pin a specific version string.
  • storageMb — persistent volume size in MB.

hooks

Commands that run inside your app container at deploy time.

  • on_deploy — runs on every deploy (new and incremental). For migrations: prisma migrate deploy, rails db:migrate, alembic upgrade head.
  • on_new — runs only the first time an environment is created, after the database is seeded. For one-time setup: create admin user, provision an API key, etc.

env

Shared environment variables. Keys/values are upserted (existing keys not in the file are left alone). Encrypted at rest with AES-256-GCM. For real secrets you don't want in git, set them in the dashboard instead.

containers

Extra containers that deploy with your app — workers, separate APIs, background jobs. Reconciled by name: containers in the file are upserted, ones removed from the file get torn down.

  • name — lowercase, alphanumeric + hyphens.
  • dockerfile, context, port, cpu, memory — same as the top-level app.
  • public — if true, the container gets its own preview subdomain. Default false (internal-only).
  • command — override the image CMD. Required for jobs.
  • typeservice (default, long-running) or job (runs once per deploy, must set command).
  • depends_on — list of sibling container names this one waits on. Nexos walks the DAG topologically, so independent containers build in parallel.
  • env — per-container overrides on top of top-level env.
  • default — if true, the preview URL routes to this container instead of app. At most one container can set it.
  • run_hooks — if true, hooks run inside this container instead of app. At most one container can set it.

nodePool

Which compute pool to schedule onto.

  • typeshared (default, runs on the global pool) or private (only your or your team's nodes).

preview

Build mode for preview environments. See Dev Preview Mode.

  • modeprod (default, compile every deploy), dev (always hot-reload), or draft-based (draft PRs hot-reload, ready PRs compile).

Per-container dev overrides live on each entry in containers: dev_command, dev_install, dev_image, and dev_watch (globs that force a type: job to re-run on a sync).

Errors and safety

  • A broken YAML in a commit is logged and skipped — the deploy still runs with the last good config. Check the deployment logs for the parse error.
  • The dashboard editor validates before applying, so paste-and-apply is non-destructive if the file is broken.
  • Real secrets belong in dashboard env vars, not committed env: blocks.

See also