Deploy YAML — field reference
The complete podmaker.sh/v1alpha manifest, field by field. The schema is
strict: unknown keys are rejected everywhere.
Top level
| Field | Type | Required | Notes |
|---|---|---|---|
apiVersion | string | ✓ | Must be podmaker.sh/v1alpha |
kind | enum | ✓ | Site or Stack |
metadata | object | ✓ | See below |
targets | array | Site | Where the site runs (≥ 1) |
source | object | Site | Where the code/image comes from |
runtime | object | Site | How it runs |
domains | array | — | Hostnames + DNS + SSL |
env | map | — | Environment variables |
deploy | object | — | Deploy strategy and hooks |
firewall | object | — | Inbound rules |
scaling | object | — | Autoscaling bounds |
stack | object | Stack | Multi-component spec |
kind: Site requires targets, source, runtime. kind: Stack requires
stack.
metadata
metadata: name: acme-web # required, ^[a-z][a-z0-9-]{0,62}$ workspace: acme # ^[a-z][a-z0-9-]{0,40}$ tags: [production, web, eu] # ≤ 20 items, each ≤ 32 chars annotations: team: platformtargets
Each entry is either a named server or a selector — not both.
targets: - server: prod-eu-web-01 # explicit server - server_selector: # or match by attributes tags: [web, eu] provider: aws region: eu-central-1 min: 2 max: 6source
One of git or image.
# git sourcesource: type: git repo: git@github.com:acme/web.git branch: main # default: main ref: <commit-or-tag> # optional, pins an exact ref auth: # ValueRef — see below from_vault: secret/acme/web#deploy_key# image sourcesource: type: image image: registry.podmaker.sh/acme/api:v1.4.2 # must be name:tag pull_secret: from_vault: secret/acme/registry#dockerconfigruntime
runtime: type: node # node|php|python|ruby|go|java|dotnet|rust|static|container version: "20" package_manager: pnpm build: command: pnpm install --frozen-lockfile && pnpm build output_dir: dist hosted: true # build on a hosted runner (default: false) start: command: node server.js port: 3000 # 1–65535 healthcheck: /healthzstatic and container runtimes typically omit build; container runs the
image directly with a start.port.
domains
domains: - hostname: acme.com dns: provider: cloudflare proxy: true # default: false ssl: provider: letsencrypt # letsencrypt|zerossl|buypass (default: letsencrypt) challenge: http-01 # http-01|dns-01 (default: http-01)env
A map of KEY: value, where each value is a ValueRef — an inline string, a
vault reference, or an env reference.
env: NODE_ENV: production # literal DATABASE_URL: from_vault: secret/acme/webdb#url # resolved at deploy time BUILD_ID: from_env: CI_COMMIT_SHA # from the deploy environmentfrom_vault follows the pattern path#key; see Vault & Secrets.
deploy
deploy: strategy: blue-green # blue-green|rolling|recreate (default: rolling) rollback_on_failure: true # default: true hooks: pre_deploy: ["./scripts/migrate.sh"] post_deploy: ["./scripts/warm-cache.sh"] health: timeout: 90s # ^\d+[smh]$ (default: 60s) retries: 5 # default: 5firewall
firewall: inbound: - { port: 80, source: "0.0.0.0/0" } # protocol default: tcp - { port: 443, protocol: tcp, source: "0.0.0.0/0" }scaling
scaling: min: 2 max: 10 metric: cpu # cpu|memory|rps|custom target: 70 # 1–100stack (kind: Stack)
A Stack groups components and optional shared services.
apiVersion: podmaker.sh/v1alphakind: Stackmetadata: name: acme-platformstack: components: - name: web source: { type: git, repo: git@github.com:acme/web.git } runtime: { type: node, version: "20", start: { port: 3000 } } depends_on: [api] - name: api source: { type: image, image: registry.podmaker.sh/acme/api:v1.4.2 } runtime: { type: container, start: { port: 8080 } } shared_services: database: { engine: postgres, version: "16", plan: small } # plan: nano|micro|small|medium|large cache: { engine: redis, version: "7" } queue: { engine: rabbitmq }Each component takes the same source, runtime, targets, domains, env,
deploy and scaling fields as a Site, plus depends_on for ordering.
ValueRef
Anywhere a secret-bearing value is accepted (source.auth,
source.pull_secret, env.*), you can use one of:
literal-string{ from_vault: "path/to/secret#key" }{ from_env: "ENV_VAR_NAME" }See worked examples next.