Skip to content

Core

The .ninedeploy manifest

Commit build, runtime, routing and storage config next to the code.

.ninedeploy is a YAML file committed in your repository root that declares how the service is built, run, routed, alerted and backed up. It removes click-through configuration drift: the panel and the file describe the same service, and the file travels with the branch.

Filenames & precedence

  • The loader accepts .ninedeploy, .ninedeploy.yml, .ninedeploy.yaml, ninedeploy.yml, ninedeploy.yaml — in that order; the first match wins.
  • The extensionless dotfile .ninedeploy is canonical and is what ninedeploy manifest init writes.
  • Files larger than 16 KiB are refused at load time.

Merge precedence

panel/DB  >  manifest  >  auto-detect

A value set in the panel always wins. If the panel is silent the manifest fills the gap, and if the manifest is silent too NineDeploy falls back to its own detection. The manifest is a project default, not a hard override — you can still run a one-off experiment from the panel without editing the file.

A representative file

.ninedeploy
version: "1"

runtime:
  type: node
  version: "20"

build:
  install: "pnpm i --frozen-lockfile"
  build: "pnpm build"
  start: "node dist/server.js"
  baseDir: "apps/api"        # monorepo sub-path

run:
  port: 3000
  healthcheck: "/healthz"
  restart: unless-stopped

env:
  required:                   # names only - values live in the env vault
    - DATABASE_URL
    - STRIPE_SECRET_KEY
  aliases:
    POSTGRES_URL: DATABASE_URL

watch:
  paths:
    - "apps/api/**"
    - "packages/**"
    - "!**/*.test.ts"

routes:
  - host: api.example.com
    ssl: true
    redirectWww: true
    rateLimit: { average: 50, burst: 100 }

database:
  ref: primary-postgres       # slug of a managed database
  env: DATABASE_URL

resources:
  cpuShares: 1024
  memMb: 512

Sections

  • runtime — language and version pinned for Nixpacks (auto | node | python | go | ruby | php | java | rust | static).
  • build — install/build/start commands, monorepo baseDir, or an explicit dockerfile that skips Nixpacks entirely.
  • run — container port, HTTP healthcheck path and restart policy (no | always | unless-stopped | on-failure[:N]).
  • static — serve a pre-built dist/ directory with SPA fallback instead of starting a process.
  • env — required variable names and aliases that rename injected managed-database variables.
  • phases — advanced Nixpacks overrides: extra Nix packages and additional build commands.
  • resources — cpuShares and memMb limits.
  • hooks — preBuild, postBuild and preStop command lines.
  • watch — glob paths that decide whether a push rebuilds this service.
  • routes — hostnames upserted into the domains table, with SSL, headers, IP allowlist and rate limits.
  • previews — ephemeral PR environment hostname pattern and retention.
  • volume — persistent mount path and its backup schedule.
  • database — managed-DB slug to attach and the env var to inject the URL into.
  • network — published host port and extra Docker network aliases.

CLI

shell
ninedeploy manifest init       # detect the project kind and scaffold a starter file
ninedeploy manifest validate   # strict schema check + secret scan
ninedeploy manifest show       # print the resolved manifest as a flat summary

The panel has the same thing under Deploy → Manifest Creator, which builds a manifest section by section and hands you the YAML to commit. Each service also has a Manifest & Traefik tab showing the manifest the last deploy actually used.

The canonical guides live in the repository's docs folder.