Reference

openship.json

The declarative deploy config for Openship — like vercel.json or railway.toml. Declare framework, build, runtime, env, domains, routes, resources, services and monorepo layout, and Openship deploys the same way every time.

openship.json is a repo-root file that tells Openship how to build, run, route, and scale a project. It mirrors what you'd otherwise set in the deploy wizard, so a repo becomes "ready to ship on Openship" and auto-deploy on push and openship deploy become deterministic — no wizard needed.

Authoritative overlay

Openship auto-detects your stack first, then applies every field present in openship.json on top. Fields you omit keep their detected value. So a good openship.json is small — declare only what you want to override or pin, not the whole detected config.

Add the $schema line for editor autocomplete and inline validation:

{
  "$schema": "https://openship.io/openship.schema.json",
  "framework": "nextjs",
  "port": 3000
}

Validate it any time with the CLI:

openship config init       # scaffold a starter openship.json
openship config validate   # check it against the schema

It's JSON, not JSONC — no comments, no trailing commas.

Build

Prop

Type

Runtime

Prop

Type

Environment variables

env is an object. A value is a plain string, or { "value", "secret" } to mark a secret (encrypted at rest — never returned to the client afterward).

{
  "env": {
    "NEXT_PUBLIC_URL": "https://app.acme.com",
    "DATABASE_URL": { "value": "postgres://…", "secret": true }
  }
}

Domains

domains is an array of hostnames or objects. A bare label ("myapp") is a free *.opsh.io-style subdomain; a dotted hostname ("app.acme.com") is a custom domain.

{ "domains": ["app.acme.com", { "domain": "api.acme.com", "port": 8080, "type": "custom" }] }

Prop

Type

Routes

routes reproduces vercel.json-style routing, compiled to the reverse proxy at deploy.

Prop

Type

Resources

Cloud sizing — a named tier, or explicit values (which become the custom tier). Ignored on self-hosted instances. See Sleep mode & resources.

Prop

Type

Services (compose)

Declaring services makes the project a multi-service (Docker) project — see Compose / multi-service. Each entry requires a name.

{
  "services": [
    { "name": "web", "build": ".", "ports": ["3000"], "exposed": true, "domain": "app.acme.com" },
    { "name": "db", "image": "postgres:17", "volumes": ["pgdata:/var/lib/postgresql/data"],
      "env": { "POSTGRES_PASSWORD": { "value": "…", "secret": true } }, "restart": "unless-stopped" }
  ]
}

Prop

Type

Monorepo

monorepo overrides Openship's detected sub-apps. Entries in apps[] are matched to detected sub-apps by rootDirectory and override their build settings — they don't declare apps from scratch (the detector finds the apps).

{
  "monorepo": {
    "workspace": { "packageManager": "pnpm", "prepareCommand": "pnpm install && pnpm codegen" },
    "apps": [
      { "name": "web", "rootDirectory": "apps/web", "framework": "nextjs", "port": 3000 },
      { "name": "api", "rootDirectory": "apps/api", "framework": "hono", "port": 8080 }
    ]
  }
}

Prop

Type

Not supported yet

sleepMode, monorepo sharedPaths, and per-app domain/env/exposed are accepted by the validator but not applied — leave them out. Set sleep mode and per-app domains in the dashboard for now.

How it maps

openship.jsonDeploy wizard / API
framework, packageManager, *Command, outputDirectory, buildImage, productionPaths, rootDirectoryBuild settings
port, productionMode, runtimeRuntime settings (hasServer, runtime isolation)
envEnvironment variables (seeded as editable rows)
domainsPublic endpoints / custom domains
routesReverse-proxy routing (routingConfig)
resourcesCloud resource tier / custom sizing
servicesCompose services
monorepoMonorepo sub-apps + workspace

See also

On this page