openship-config
GitHub用于创建或修复 openship.json 声明式部署配置文件。帮助用户配置框架、构建命令、环境变量及域名,实现项目可部署性,支持验证和初始化操作。
Trigger Scenarios
Install
npx skills add oblien/openship --skill openship-config -g -y
SKILL.md
Frontmatter
{
"name": "openship-config",
"description": "Author or fix an openship.json — Openship's declarative deploy config (like vercel.json \/ railway.toml). Use when the user asks to \"make this repo deployable on Openship\", \"add an openship.json\", \"configure the Openship deploy\", set the framework\/build\/env\/domains\/services\/resources for an Openship deploy, or fix a failing `openship config validate`."
}
Authoring openship.json
openship.json is a repo-root file that declares how Openship builds, runs, routes, and
scales a project. It is an authoritative overlay: Openship auto-detects everything first,
then every field present in openship.json overrides the detected value. Absent fields keep
the detected value — so a good openship.json is small: declare only what you want to pin
or override, not the whole detected config.
Workflow
- Understand the repo. Look at
package.json(scripts, deps), lockfiles (package manager), framework config (next.config.*,vite.config.*,astro.config.*, …), anydocker-compose.yml, and whether it's a monorepo (pnpm-workspace.yaml,turbo.json,apps/*,packages/*). - Decide what to override. If detection would already get it right, leave it out. Add a field only when the repo needs a non-default (custom build command, a fixed port, a custom domain, secrets, compose services, cloud sizing).
- Write
openship.jsonat the repo root. Always start with the$schemaline for editor autocomplete:{ "$schema": "https://openship.io/openship.schema.json" } - Validate with
openship config validate(oropenship config validate path/to/openship.json). Fix every reported error.openship config initscaffolds a starter if none exists.
The essentials (cover these first)
framework— only if detection guesses wrong. One of the stack slugs (seereferences/fields.md).buildCommand/installCommand/startCommand— the commands. Omit any that match the detected default.outputDirectory— for static/SSG builds (e.g.dist,.next,build,out).port— the port a server listens on.env— a string is a plain value;{ "value": "...", "secret": true }marks a secret (encrypted at rest). Prefer per-keysecret: truefor anything sensitive.domains— a bare label ("myapp") is a free subdomain; a dotted hostname ("app.acme.com") is a custom domain.
Common shapes
Static site
{
"$schema": "https://openship.io/openship.schema.json",
"framework": "vite",
"buildCommand": "pnpm build",
"outputDirectory": "dist",
"productionMode": "static"
}
Server app with a custom domain + secret
{
"$schema": "https://openship.io/openship.schema.json",
"framework": "nextjs",
"port": 3000,
"runtime": "docker",
"env": {
"NEXT_PUBLIC_URL": "https://app.acme.com",
"DATABASE_URL": { "value": "postgres://…", "secret": true }
},
"domains": ["app.acme.com"]
}
Compose services — declaring services makes it a multi-service project (Docker runtime):
{
"$schema": "https://openship.io/openship.schema.json",
"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" }
]
}
Rules & gotchas
- It's JSON, not JSONC — no comments, no trailing commas.
- Keep it minimal. Every field overrides detection; unused fields just add noise.
services(compose) andmonorepoare alternatives to a single-app config, not additions.monorepo.apps[]entries override detected sub-apps matched byrootDirectory; they don't declare apps from scratch (Openship's detector finds the apps).resourcesis a cloud concern (tier or explicit cpu/mem/disk); it's ignored on self-hosted.runtime,productionMode,domains,resourcesseed the deploy wizard and headless deploys.sleepModeand monoreposharedPathsare not supported yet — don't add them.
The full field-by-field reference (every field, its type, allowed values, and what it maps to)
is in references/fields.md. Read it before writing anything non-trivial.
Version History
- 6a67736 Current 2026-07-30 20:37


