Claude Cursor Skill

openship-config

This skill should be used when the user asks to "create openship.json", "configure an OpenShip deployment", "make a repo deployable on OpenShip", or fix "openship config validate" errors.

LLM Mart · 0 points · 7 views 0 listing impressions 0 install-command copies
Virus-scanned Reviewed automatically before listing.

Full trust report

Download fcakyon-claude-codex-settings-plugins_openship-skills_skills_openship-config-4632eb3.zip · 25 KB
Part of fcakyon/claude-codex-settings — 83 skills

Install

skills CLI npx skills add https://github.com/fcakyon/claude-codex-settings/tree/main/plugins/openship-skills/skills/openship-config
Claude Code claude plugin marketplace add https://llmmart.ai/marketplace.json && claude plugin install fcakyon-claude-codex-settings@llmmart
Git git clone https://github.com/fcakyon/claude-codex-settings.git

The skills CLI installs just this skill, for any of its supported agents. Claude Code installs the whole fcakyon/claude-codex-settings collection as a plugin from our marketplace. Git is the plain clone.

Skill manifest

Design openship.json

Use OpenShip's upstream configuration workflow: inspect the repo, declare only necessary overrides, then validate. Auto-detection supplies omitted fields. Prefer self-hosted deployment unless the user selects cloud.

Design the configuration

  1. Inspect package scripts, lockfiles, framework settings, Dockerfiles, compose files, workspace layout, and an existing openship.json.
  2. Choose a single app, compose services, or detected monorepo apps. Do not combine those shapes casually. monorepo.apps overrides detected apps by root directory. It does not discover new applications.
  3. Read fields for names and meanings and the bundled JSON schema for editor validation. Use compose guidance for service topology, ports, dependencies, and persistent volumes.
  4. Start with openship config init only when the file is absent. Preserve an existing config and add only values that need to override detection. Keep its $schema set to https://openship.io/openship.schema.json.
  5. Run openship --json config validate using the deployment's CLI version. Fix errors and review warnings: unknown keys can be ignored by the runtime even though the editor schema rejects them.

A minimal server config can be:

{
  "$schema": "https://openship.io/openship.schema.json",
  "port": 3000,
  "runtime": "docker",
  "domains": ["app.example.com"]
}

Self-hosted details

  • Self-hosted defaults to unlimited resources in the bundled release. Declare caps only when intended. Service-level caps override project caps field by field. Check target capacity separately from local config validation.
  • Use named persistent volumes for state that must survive an application deploy. Expose only the services intended to receive public traffic.
  • Keep actual secret values out of committed JSON. secret: true controls storage handling after ingestion. It does not encrypt a credential in a Git file. Read environment variables for instance-managed values.
  • openship.json expresses desired configuration. It does not prove an existing domain has moved or the running deployment has changed. The companion openship-deploy skill handles deployment and live verification.

Source and version

The workflow and field reference derive from the official upstream config skill. upstream.json records the release and links to its CLI validator, runtime parser, types, parser tests, and deployment preparation code. Consult those sources when docs disagree or a behavior depends on the installed version. The parser and actual deployment implementation decide runtime behavior. The JSON schema serves editor validation.

Read the configuration guide for additional examples. Do not copy example credentials into a repository.

Files (claude-codex-settings)
  • references
    • compose-multi-service.mdx 16.8 KB · in bundle
    • environment-variables.mdx 10 KB · in bundle
    • fields.md 6.5 KB
      # `openship.json` — full field reference
      
      Every field is optional. Present fields override auto-detection; absent fields keep the detected
      value. Validated by `openship config validate` (same parser the deploy uses).
      
      ## Build
      
      | Field | Type | Notes |
      |---|---|---|
      | `framework` | enum | Stack slug (see list below). Overrides detection. |
      | `packageManager` | enum | `npm` `yarn` `pnpm` `bun` `go` `cargo` `pip` `poetry` `pipenv` `uv` `bundler` `composer` `maven` `gradle` `dotnet` `mix` |
      | `rootDirectory` | string | App dir relative to repo root (e.g. `./`, `apps/web`). |
      | `composePath` | string | Compose file outside the detected root — the file (`deploy/stack.yml`, which also covers non-standard names) or the folder holding it (`deploy/docker-compose`). Makes the project a compose deploy; `build:` contexts resolve relative to that folder, as compose does. |
      | `installCommand` | string | Dependency install command. |
      | `buildCommand` | string | Build command. |
      | `startCommand` | string | Production start command. |
      | `outputDirectory` | string | Build output dir (`dist`, `.next`, `build`, `out`, …). |
      | `buildImage` | string | Build Docker image (e.g. `node:22`). |
      | `productionPaths` | string[] | Paths shipped as the production artifact. |
      
      **`framework` values:** `nextjs` `nuxt` `sveltekit` `remix` `astro` `vite` `angular` `gatsby`
      `cra` `vue` `react` `express` `fastify` `hono` `nestjs` `koa` `adonis` `elysia` `go` `gin`
      `fiber` `echo` `rust` `actix` `axum` `rocket` `python` `django` `flask` `fastapi` `rails`
      `sinatra` `laravel` `symfony` `springboot` `quarkus` `kotlin` `dotnet` `blazor` `phoenix`
      `node` `static` `docker` `docker-compose` `webmail`.
      
      ## Runtime
      
      | Field | Type | Notes |
      |---|---|---|
      | `runtime` | `bare` \| `docker` | Runtime isolation for a single app. Services/docker projects are always `docker`. Seeds a new deploy's runtime. |
      | `productionMode` | `host` \| `static` \| `standalone` | `static` ⇒ served as files, no server (sets `hasServer=false`). |
      | `port` | integer 1–65535 | Server port. |
      | `volumes` | string[] | Paths kept across deploys. Bare path = relative to the app (`storage`), or a full mount (`uploads:/app/storage`, `/srv/data:/app/var`). Omit to inherit the framework defaults (Laravel keeps `storage/`); `[]` turns persistence off. Compose services use `services[].volumes` instead. |
      
      ## Env
      
      `env` is an object. A value is either a plain string, or `{ "value": string, "secret"?: boolean }`.
      `secret: true` marks the variable for encryption at rest.
      
      ```json
      "env": {
        "PUBLIC_URL": "https://app.acme.com",
        "API_KEY": { "value": "sk_live_…", "secret": true }
      }
      ```
      
      ## Domains
      
      `domains` is an array. Each entry is either a hostname string, or an object:
      
      | Field | Type | Notes |
      |---|---|---|
      | `domain` | string | Hostname. Bare label = free subdomain; dotted = custom. |
      | `port` | integer | Which port this hostname routes to. |
      | `targetPath` | string | Path prefix on the target (default `/`). |
      | `type` | `free` \| `custom` | Overrides the free/custom inference. |
      
      ## Routes
      
      `routes` compiles to the reverse proxy at deploy.
      
      | Field | Type | Notes |
      |---|---|---|
      | `rewrites` | `{ source, destination }[]` | Internal rewrites (e.g. SPA fallback). |
      | `redirects` | `{ source, destination, permanent?, statusCode? }[]` | 3xx redirects. |
      | `headers` | `{ source, headers: { key, value }[] }[]` | Response headers per path. |
      | `cleanUrls` | boolean | Strip `.html`. |
      | `trailingSlash` | boolean | Enforce/remove trailing slash. |
      
      ## Resources
      
      `resources` is a named tier OR explicit values. Explicit values become the `custom` tier.
      
      **Self-hosted defaults to `unlimited`** — no caps, because the machine is the operator's own and
      is itself the ceiling. Only declare this to deliberately cap a container. A non-zero value is
      validated against the TARGET MACHINE's real capacity, so a big box can be used fully. Cloud
      workspaces are metered and must be sized: `unlimited` is rejected there and an omitted value
      falls back to `low`.
      
      | Field | Type | Range |
      |---|---|---|
      | `tier` | `unlimited` \| `micro` \| `low` \| `medium` \| `high` | `unlimited` is self-hosted only |
      | `cpuCores` | number | `0` = no limit; otherwise ≥ 0.25, up to the machine's cores |
      | `memoryMb` | integer | `0` = no limit; otherwise ≥ 128, up to the machine's RAM |
      | `diskMb` | integer | `0` = no limit; otherwise 64–204800 (cloud workspaces only) |
      
      ## Services (compose)
      
      `services` is an array; declaring it makes the project a multi-service (Docker) project.
      To deploy an EXISTING compose file instead of re-declaring its services here, set
      [`composePath`](#build) and leave `services` out.
      
      | Field | Type | Notes |
      |---|---|---|
      | `name` | string | **Required.** |
      | `image` | string | Prebuilt image (e.g. `postgres:17`). |
      | `build` | string | Build context path. |
      | `dockerfile` | string | Dockerfile path. |
      | `ports` | string[] | e.g. `["3000"]`, `["5432:5432"]`. |
      | `volumes` | string[] | e.g. `["pgdata:/var/lib/postgresql/data"]`. |
      | `dependsOn` | string[] | Other service names. |
      | `env` | env object | Same shape as top-level `env`. |
      | `command` | string | Override the container command. |
      | `restart` | `no` \| `always` \| `on-failure` \| `unless-stopped` | Restart policy. |
      | `exposed` | boolean | Publicly routed. |
      | `exposedPort` | string | Which container port is exposed. |
      | `domain` | string | Public hostname for this service. |
      | `healthcheck` | object | `{ test, interval, timeout, retries, startPeriod, disable }`. |
      | `resources` | object | Per-service caps, overriding the top-level `resources` field by field. Same shape; `0` = no limit. |
      
      A compose file's own `mem_limit` / `cpus` / `deploy.resources.limits` are read and applied the
      same way — no need to restate them here.
      
      ## Monorepo
      
      `monorepo` overrides detected sub-apps.
      
      | Field | Type | Notes |
      |---|---|---|
      | `workspace.packageManager` | string | Root workspace package manager. |
      | `workspace.prepareCommand` | string | Runs once at the repo root before per-app builds. |
      | `apps[]` | array | Per-sub-app build overrides. |
      
      Each `apps[]` entry (`name` + `rootDirectory` required) overrides the detected sub-app at that
      `rootDirectory`. Supported overrides: `framework`, `packageManager`, `installCommand`,
      `buildCommand`, `startCommand`, `outputDirectory`, `buildImage`, `port`. (Per-app `domain`/`env`
      are set in the wizard, not here.)
      
      ## Not supported (do not add)
      
      `sleepMode`, monorepo `sharedPaths`, and per-app `domain`/`env`/`exposed` are validated leniently
      but **not applied** — leave them out.
      
    • openship-json.mdx 3.2 KB · in bundle
    • openship.schema.json 13.5 KB
      {
        "$schema": "http://json-schema.org/draft-07/schema#",
        "$id": "https://openship.io/openship.schema.json",
        "title": "Openship deploy config",
        "description": "openship.json — declarative deploy config for Openship. Auto-detection runs first; every field present here overrides it. Absent fields keep the detected value.",
        "type": "object",
        "additionalProperties": false,
        "properties": {
          "$schema": { "type": "string" },
      
          "framework": {
            "description": "Stack/framework slug. Overrides auto-detection.",
            "enum": [
              "nextjs",
              "nuxt",
              "sveltekit",
              "remix",
              "astro",
              "vite",
              "angular",
              "gatsby",
              "cra",
              "vue",
              "react",
              "express",
              "fastify",
              "hono",
              "nestjs",
              "koa",
              "adonis",
              "elysia",
              "go",
              "gin",
              "fiber",
              "echo",
              "rust",
              "actix",
              "axum",
              "rocket",
              "python",
              "django",
              "flask",
              "fastapi",
              "rails",
              "sinatra",
              "laravel",
              "symfony",
              "springboot",
              "quarkus",
              "kotlin",
              "dotnet",
              "blazor",
              "phoenix",
              "node",
              "static",
              "docker",
              "docker-compose",
              "unknown",
              "webmail"
            ]
          },
          "packageManager": {
            "description": "Package manager used for install/build.",
            "enum": [
              "npm",
              "yarn",
              "pnpm",
              "bun",
              "go",
              "cargo",
              "pip",
              "poetry",
              "pipenv",
              "uv",
              "bundler",
              "composer",
              "maven",
              "gradle",
              "dotnet",
              "mix"
            ]
          },
          "rootDirectory": {
            "description": "Directory the app lives in, relative to the repo root (e.g. \"./\", \"apps/web\").",
            "type": "string"
          },
          "composePath": {
            "description": "Compose file kept outside the detected root — either the file itself (\"deploy/stack.yml\", which also covers non-standard filenames) or the directory holding it (\"deploy/docker-compose\"). Makes the project a compose deploy; service \"build\" contexts resolve relative to that directory, as compose does.",
            "type": "string"
          },
          "installCommand": { "description": "Command that installs dependencies.", "type": "string" },
          "buildCommand": { "description": "Command that builds the app.", "type": "string" },
          "startCommand": {
            "description": "Command that starts the server in production.",
            "type": "string"
          },
          "outputDirectory": {
            "description": "Directory the build writes to (e.g. \".next\", \"dist\").",
            "type": "string"
          },
          "buildImage": {
            "description": "Docker image used for the build (e.g. \"node:22\").",
            "type": "string"
          },
          "productionPaths": {
            "description": "Paths shipped to the runtime as the production artifact.",
            "type": "array",
            "items": { "type": "string" }
          },
          "volumes": {
            "description": "Paths kept across deploys. A bare path is relative to the app (\"storage\"); a full mount also works (\"uploads:/app/storage\", \"/srv/data:/app/storage\"). Omit to inherit the framework's defaults; [] turns persistence off.",
            "type": "array",
            "items": { "type": "string" }
          },
      
          "runtime": {
            "description": "Runtime isolation for a single app. Services/docker projects are always \"docker\".",
            "enum": ["bare", "docker"]
          },
          "productionMode": {
            "description": "How the app is served. \"static\" ⇒ no server (files only).",
            "enum": ["host", "static", "standalone"]
          },
          "port": {
            "description": "Port the server listens on.",
            "type": "integer",
            "minimum": 1,
            "maximum": 65535
          },
      
          "env": {
            "description": "Environment variables. A string is a plain value; { \"value\", \"secret\" } marks a secret.",
            "type": "object",
            "additionalProperties": {
              "oneOf": [
                { "type": "string" },
                {
                  "type": "object",
                  "additionalProperties": false,
                  "required": ["value"],
                  "properties": {
                    "value": { "type": "string" },
                    "secret": { "type": "boolean" }
                  }
                }
              ]
            }
          },
      
          "domains": {
            "description": "Public domains. A string is a hostname (a bare label = free subdomain; a dotted name = custom).",
            "type": "array",
            "items": {
              "oneOf": [
                { "type": "string" },
                {
                  "type": "object",
                  "additionalProperties": false,
                  "required": ["domain"],
                  "properties": {
                    "domain": { "type": "string" },
                    "port": { "type": "integer", "minimum": 1, "maximum": 65535 },
                    "targetPath": { "type": "string" },
                    "type": { "enum": ["free", "custom"] }
                  }
                }
              ]
            }
          },
      
          "routes": {
            "description": "Reverse-proxy routing rules compiled to OpenResty at deploy.",
            "type": "object",
            "additionalProperties": false,
            "properties": {
              "rewrites": {
                "type": "array",
                "items": {
                  "type": "object",
                  "additionalProperties": false,
                  "required": ["source", "destination"],
                  "properties": {
                    "source": { "type": "string" },
                    "destination": { "type": "string" }
                  }
                }
              },
              "redirects": {
                "type": "array",
                "items": {
                  "type": "object",
                  "additionalProperties": false,
                  "required": ["source", "destination"],
                  "properties": {
                    "source": { "type": "string" },
                    "destination": { "type": "string" },
                    "permanent": { "type": "boolean" },
                    "statusCode": { "type": "integer", "minimum": 300, "maximum": 399 }
                  }
                }
              },
              "headers": {
                "type": "array",
                "items": {
                  "type": "object",
                  "additionalProperties": false,
                  "required": ["source", "headers"],
                  "properties": {
                    "source": { "type": "string" },
                    "headers": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "additionalProperties": false,
                        "required": ["key", "value"],
                        "properties": {
                          "key": { "type": "string" },
                          "value": { "type": "string" }
                        }
                      }
                    }
                  }
                }
              },
              "cleanUrls": { "type": "boolean" },
              "trailingSlash": { "type": "boolean" }
            }
          },
      
          "resources": {
            "description": "CPU/memory limits for this project's containers: a named tier OR explicit values (which becomes the custom tier). Self-hosted defaults to unlimited (the machine is the ceiling) and validates a non-zero value against the target machine's real capacity; cloud workspaces are metered and must be sized. 0 = no limit.",
            "type": "object",
            "additionalProperties": false,
            "properties": {
              "tier": { "enum": ["unlimited", "micro", "low", "medium", "high"] },
              "cpuCores": { "type": "number", "minimum": 0, "maximum": 1024 },
              "memoryMb": { "type": "integer", "minimum": 0, "maximum": 4194304 },
              "diskMb": { "type": "integer", "minimum": 0, "maximum": 204800 }
            }
          },
      
          "services": {
            "description": "Compose services. Declaring services makes this a multi-service project.",
            "type": "array",
            "items": {
              "type": "object",
              "additionalProperties": false,
              "required": ["name"],
              "properties": {
                "name": { "type": "string" },
                "image": { "type": "string" },
                "build": { "type": "string" },
                "dockerfile": { "type": "string" },
                "buildArgs": {
                  "description": "Per-service Docker build arguments. null inherits the same-named value from top-level env; string values override it. Do not put secrets directly in buildArgs.",
                  "type": "object",
                  "propertyNames": { "pattern": "^[A-Za-z_][A-Za-z0-9_]*$" },
                  "additionalProperties": { "type": ["string", "null"] }
                },
                "ports": { "type": "array", "items": { "type": "string" } },
                "volumes": { "type": "array", "items": { "type": "string" } },
                "dependsOn": { "type": "array", "items": { "type": "string" } },
                "env": {
                  "type": "object",
                  "additionalProperties": {
                    "oneOf": [
                      { "type": "string" },
                      {
                        "type": "object",
                        "additionalProperties": false,
                        "required": ["value"],
                        "properties": {
                          "value": { "type": "string" },
                          "secret": { "type": "boolean" }
                        }
                      }
                    ]
                  }
                },
                "command": { "type": "string" },
                "restart": { "enum": ["no", "always", "on-failure", "unless-stopped"] },
                "exposed": { "type": "boolean" },
                "exposedPort": { "type": "string" },
                "domain": { "type": "string" },
                "healthcheck": {
                  "type": "object",
                  "additionalProperties": false,
                  "properties": {
                    "test": {
                      "oneOf": [{ "type": "string" }, { "type": "array", "items": { "type": "string" } }]
                    },
                    "interval": { "type": "string" },
                    "timeout": { "type": "string" },
                    "retries": { "type": "integer", "minimum": 0, "maximum": 100 },
                    "startPeriod": { "type": "string" },
                    "disable": { "type": "boolean" }
                  }
                },
                "resources": {
                  "description": "Per-service cpu/memory caps, overriding the top-level resources field by field. Parity with compose mem_limit / deploy.resources.limits, which Openship also reads off the compose file. 0 = no limit.",
                  "type": "object",
                  "additionalProperties": false,
                  "properties": {
                    "tier": { "enum": ["unlimited", "micro", "low", "medium", "high"] },
                    "cpuCores": { "type": "number", "minimum": 0, "maximum": 1024 },
                    "memoryMb": { "type": "integer", "minimum": 0, "maximum": 4194304 },
                    "diskMb": { "type": "integer", "minimum": 0, "maximum": 204800 }
                  }
                }
              }
            }
          },
      
          "monorepo": {
            "description": "Monorepo workspace + per-sub-app build overrides (matched to detected apps by rootDirectory).",
            "type": "object",
            "additionalProperties": false,
            "properties": {
              "workspace": {
                "type": "object",
                "additionalProperties": false,
                "required": ["packageManager"],
                "properties": {
                  "packageManager": { "type": "string" },
                  "prepareCommand": { "type": "string" }
                }
              },
              "apps": {
                "type": "array",
                "items": {
                  "type": "object",
                  "additionalProperties": false,
                  "required": ["name", "rootDirectory"],
                  "properties": {
                    "name": { "type": "string" },
                    "rootDirectory": { "type": "string" },
                    "framework": {
                      "enum": [
                        "nextjs",
                        "nuxt",
                        "sveltekit",
                        "remix",
                        "astro",
                        "vite",
                        "angular",
                        "gatsby",
                        "cra",
                        "vue",
                        "react",
                        "express",
                        "fastify",
                        "hono",
                        "nestjs",
                        "koa",
                        "adonis",
                        "elysia",
                        "go",
                        "gin",
                        "fiber",
                        "echo",
                        "rust",
                        "actix",
                        "axum",
                        "rocket",
                        "python",
                        "django",
                        "flask",
                        "fastapi",
                        "rails",
                        "sinatra",
                        "laravel",
                        "symfony",
                        "springboot",
                        "quarkus",
                        "kotlin",
                        "dotnet",
                        "blazor",
                        "phoenix",
                        "node",
                        "static",
                        "docker",
                        "docker-compose",
                        "unknown",
                        "webmail"
                      ]
                    },
                    "packageManager": {
                      "enum": [
                        "npm",
                        "yarn",
                        "pnpm",
                        "bun",
                        "go",
                        "cargo",
                        "pip",
                        "poetry",
                        "pipenv",
                        "uv",
                        "bundler",
                        "composer",
                        "maven",
                        "gradle",
                        "dotnet",
                        "mix"
                      ]
                    },
                    "installCommand": { "type": "string" },
                    "buildCommand": { "type": "string" },
                    "startCommand": { "type": "string" },
                    "outputDirectory": { "type": "string" },
                    "buildImage": { "type": "string" },
                    "port": { "type": "integer", "minimum": 1, "maximum": 65535 }
                  }
                }
              }
            }
          }
        }
      }
      
    • upstream.json 4 KB
      {
        "repository": "https://github.com/oblien/openship",
        "ref": "v0.7.2",
        "commit": "541ba903fdcd8959054b1fb8805749632a1dafe9",
        "files": {
          ".claude/skills/openship-config/SKILL.md": {
            "url": "https://github.com/oblien/openship/blob/541ba903fdcd8959054b1fb8805749632a1dafe9/.claude/skills/openship-config/SKILL.md",
            "sha256": "a3f86d4b417ea06eb67c3e648b835c013ea6ac4b6f7fc25732363cbaf8a66df6"
          },
          ".claude/skills/openship-config/references/fields.md": {
            "url": "https://github.com/oblien/openship/blob/541ba903fdcd8959054b1fb8805749632a1dafe9/.claude/skills/openship-config/references/fields.md",
            "sha256": "583b8adb4c1fb51aa2ae1e2c28984430741a5dfbcbc72d33088cfb543b32ba15"
          },
          "LICENSE": {
            "url": "https://github.com/oblien/openship/blob/541ba903fdcd8959054b1fb8805749632a1dafe9/LICENSE",
            "sha256": "cfc7749b96f63bd31c3c42b5c471bf756814053e847c10f3eb003417bc523d30"
          },
          "apps/api/src/modules/deployments/prepare.service.ts": {
            "url": "https://github.com/oblien/openship/blob/541ba903fdcd8959054b1fb8805749632a1dafe9/apps/api/src/modules/deployments/prepare.service.ts",
            "sha256": "417765dfe614bd58d50a19a15cb5b9afbe8ee2359dc45877ffe4ba8b9e7156db"
          },
          "apps/cli/src/commands/config.ts": {
            "url": "https://github.com/oblien/openship/blob/541ba903fdcd8959054b1fb8805749632a1dafe9/apps/cli/src/commands/config.ts",
            "sha256": "c2d10f0af7968969054e395dbb4603afb0844698e8a02866df8dd8716314e90a"
          },
          "apps/cli/src/commands/server.ts": {
            "url": "https://github.com/oblien/openship/blob/541ba903fdcd8959054b1fb8805749632a1dafe9/apps/cli/src/commands/server.ts",
            "sha256": "278ac25a19577ea06d7edead59a9cf046ae2fee80ff66de47373ca1f1a52ef68"
          },
          "apps/cli/src/commands/service.ts": {
            "url": "https://github.com/oblien/openship/blob/541ba903fdcd8959054b1fb8805749632a1dafe9/apps/cli/src/commands/service.ts",
            "sha256": "9ef53a6e8f39edd0bac03759b81bb4aaa3fd0567220f702034b7c7bbf9caf212"
          },
          "apps/web/content/docs/guides/compose-multi-service.mdx": {
            "url": "https://github.com/oblien/openship/blob/541ba903fdcd8959054b1fb8805749632a1dafe9/apps/web/content/docs/guides/compose-multi-service.mdx",
            "sha256": "829d13e15b296e4f0e18fe421864858d357cd58cd9a0743e8358c9e8be040db7"
          },
          "apps/web/content/docs/guides/environment-variables.mdx": {
            "url": "https://github.com/oblien/openship/blob/541ba903fdcd8959054b1fb8805749632a1dafe9/apps/web/content/docs/guides/environment-variables.mdx",
            "sha256": "7afd882d19102abf747b91fddef0f82a176ee054c6dccc071ba95509ce876fbd"
          },
          "apps/web/content/docs/guides/openship-json.mdx": {
            "url": "https://github.com/oblien/openship/blob/541ba903fdcd8959054b1fb8805749632a1dafe9/apps/web/content/docs/guides/openship-json.mdx",
            "sha256": "d674d25ff5c2b525b090fb74be9c0bea0fe53e2db953f2d36303b03cf9562637"
          },
          "apps/web/public/openship.schema.json": {
            "url": "https://github.com/oblien/openship/blob/541ba903fdcd8959054b1fb8805749632a1dafe9/apps/web/public/openship.schema.json",
            "sha256": "a8830ea052a389b4d010cb8d9cdc0dbc72bec183ed638d7606d6ca195f1e53b9"
          },
          "packages/core/src/openship-config/parse.test.ts": {
            "url": "https://github.com/oblien/openship/blob/541ba903fdcd8959054b1fb8805749632a1dafe9/packages/core/src/openship-config/parse.test.ts",
            "sha256": "9173184da7c4849b3dbe5a49ad9ca890f799606daddeab8b5a75eb4745966146"
          },
          "packages/core/src/openship-config/parse.ts": {
            "url": "https://github.com/oblien/openship/blob/541ba903fdcd8959054b1fb8805749632a1dafe9/packages/core/src/openship-config/parse.ts",
            "sha256": "e56afac4917516f496476653fc71a0b65d42c4435bc87cf58daf064ccb182c62"
          },
          "packages/core/src/openship-config/schema.ts": {
            "url": "https://github.com/oblien/openship/blob/541ba903fdcd8959054b1fb8805749632a1dafe9/packages/core/src/openship-config/schema.ts",
            "sha256": "1728161dd2746677218036c96d45663c0cab185d82552be21e280032ab15dbc7"
          }
        }
      }
      
  • LICENSE 11.1 KB · in bundle
  • SKILL.md 3.1 KB
    ---
    name: openship-config
    description: This skill should be used when the user asks to "create openship.json", "configure an OpenShip deployment", "make a repo deployable on OpenShip", or fix "openship config validate" errors.
    ---
    
    # Design openship.json
    
    Use OpenShip's upstream configuration workflow: inspect the repo, declare only necessary overrides, then validate. Auto-detection supplies omitted fields. Prefer self-hosted deployment unless the user selects cloud.
    
    ## Design the configuration
    
    1. Inspect package scripts, lockfiles, framework settings, Dockerfiles, compose files, workspace layout, and an existing `openship.json`.
    2. Choose a single app, compose services, or detected monorepo apps. Do not combine those shapes casually. `monorepo.apps` overrides detected apps by root directory. It does not discover new applications.
    3. Read [fields](references/fields.md) for names and meanings and the bundled [JSON schema](references/openship.schema.json) for editor validation. Use [compose guidance](references/compose-multi-service.mdx) for service topology, ports, dependencies, and persistent volumes.
    4. Start with `openship config init` only when the file is absent. Preserve an existing config and add only values that need to override detection. Keep its `$schema` set to `https://openship.io/openship.schema.json`.
    5. Run `openship --json config validate` using the deployment's CLI version. Fix errors and review warnings: unknown keys can be ignored by the runtime even though the editor schema rejects them.
    
    A minimal server config can be:
    
    ```json
    {
      "$schema": "https://openship.io/openship.schema.json",
      "port": 3000,
      "runtime": "docker",
      "domains": ["app.example.com"]
    }
    ```
    
    ## Self-hosted details
    
    - Self-hosted defaults to unlimited resources in the bundled release. Declare caps only when intended. Service-level caps override project caps field by field. Check target capacity separately from local config validation.
    - Use named persistent volumes for state that must survive an application deploy. Expose only the services intended to receive public traffic.
    - Keep actual secret values out of committed JSON. `secret: true` controls storage handling after ingestion. It does not encrypt a credential in a Git file. Read [environment variables](references/environment-variables.mdx) for instance-managed values.
    - `openship.json` expresses desired configuration. It does not prove an existing domain has moved or the running deployment has changed. The companion `openship-deploy` skill handles deployment and live verification.
    
    ## Source and version
    
    The workflow and [field reference](references/fields.md) derive from the official upstream config skill. [upstream.json](references/upstream.json) records the release and links to its CLI validator, runtime parser, types, parser tests, and deployment preparation code. Consult those sources when docs disagree or a behavior depends on the installed version. The parser and actual deployment implementation decide runtime behavior. The JSON schema serves editor validation.
    
    Read the [configuration guide](references/openship-json.mdx) for additional examples. Do not copy example credentials into a repository.
    

Comments (0)

Sign in to join the conversation.

No comments yet.

Reviews (0)

No reviews yet.

Related