Skip to main content

pagifier.yaml reference

Two kinds of file exist. The root file lists deployable projects (nothing is ever auto-discovered); each project file completely defines one deployment.

TOML is the primary format (pagifier.toml); YAML (pagifier.yaml) is fully supported with identical keys — Pagifier detects the format from content. Get editor autocomplete with the published JSON Schema:

#:schema https://pagifier.company.com/v1/schema/pagifier.json
# yaml-language-server: $schema=https://pagifier.company.com/v1/schema/pagifier.json

Root file

pagifier.toml
version = 1

projects = [
"frontend/pagifier.toml",
"admin/pagifier.toml",
"api/pagifier.toml",
]

Project file

KeyRequiredNotes
versionyesMust be 1.
nameyesLowercase DNS label; becomes the workload name.
environmentyesdev qa uat staging prod preview. Selects the environment profile. preview apps are ephemeral: hostname auto-generated, garbage-collected after a TTL.
runtimeyes*static, node, python, or go. *May be supplied by the template.
templatenoPlatform template, optionally pinned: react-static@2.
hanotrue adds minimum replicas, anti-affinity, topology spread, a PodDisruptionBudget, and zero-downtime rollout.
portyes*Container port. Never guessed. *Node apps may use runtimeConfig.port instead.
autoRollbacknotrue reverts automatically when a rollout stalls. Usually set by environment profiles.
build.enablednofalse packages the uploaded artifact as-is.
build.workDir, build.commandswith buildCommands run verbatim in the toolchain image. Never inferred.
artifact.directorystaticDirectory shipped into the image — nothing else leaves the build. Optional for server runtimes (e.g. ship only a compiled Go binary).
server.typenonginx (the only static server); defaulted when omitted.
runtimeConfig.commandserver runtimesMandatory start command for node/python/go. package.json, requirements.txt, and go.mod are never read.
resourcesnocpu, memory (requests), cpuLimit, memoryLimit. Memory limit defaults to the request.
ingressnohost (required if enabled), path, className, tls (default on), annotations. mode: gateway renders a Gateway API HTTPRoute; the parent gateway: {name, namespace, sectionName} usually comes from the environment profile.
autoscalingnoenabled, minReplicas, maxReplicas, cpu, memory (target %). Declaring triggers (KEDA scalers) renders a ScaledObject instead of an HPA.
envnoPlain environment variables.
secretsnoprovider (kubernetes aws vault external-secrets), keys mapping ENV_VAR → remote key, storeRef, refreshInterval. See the secrets guide.
secretFilesnoFile name → {source, mountPath}.
headers.corsnoenabled, allowOrigins, allowMethods, allowHeaders, maxAge.
headers.customnoExtra response headers.
authenticationnobasic (htpasswd secret, enforced in nginx); oidc / jwt / oauth2-proxy enforced at the ingress via platform middleware — projects cannot override those annotations.
compressionnogzip (default on), brotli.
security.profilenobasic recommended strict internal pci — expands to response headers from the platform library.
cache.static, cache.htmlnomaxAge in compact form: 365d, 12h, 5m, 30s.
routesnoPath-based proxying: {path, service, port, authentication}.
healthChecknopath plus probe timings.
deploynoDeployment strategy — see deployment strategies.

Shorthands

Common cases have compact spellings. They are pure syntax — each expands to the canonical object form before template merging, so a shorthand still deep-merges with whatever the templates set:

Shorthand (TOML)Expands to
ingress = "app.company.com"[ingress] with host
build = ["npm ci", "npm run build"][build] with enabled = true + commands
build = false[build] with enabled = false
artifact = "dist"[artifact] with directory
runtimeConfig = "node dist/main.js"[runtimeConfig] with command
security = "strict"[security] with profile
healthCheck = "/health"[healthCheck] with path
authentication = "basic"[authentication] enabled with type
compression = false[compression] with gzip = false
cache = {static = "365d", html = "5m"}per-rule maxAge tables
deploy = "canary"[deploy] with strategy
analysis = ["error-rate"]named gate references

The YAML spellings are the same shapes (ingress: app.company.com, build: [npm ci, npm run build], deploy: canary, …).

Merge order

platform defaults → runtime template → application template
→ environment profile → your pagifier.yaml

Your file always wins. Maps merge deep, lists replace whole, null deletes a key inherited from a template. Unknown keys are rejected — with a suggestion when it looks like a typo (unknown field "artefact" — did you mean "artifact"?).

To see exactly what the merge produced for a running release:

curl -H "Authorization: Bearer $TOKEN" \
https://pagifier.company.com/v1/applications/my-app/environments/prod/releases/RELEASE_ID/config

Validating with CUE

Prefer CUE over JSON Schema? The same contract is published as a CUE schema, with all shorthand forms expressed as disjunctions:

curl -sO https://pagifier.company.com/v1/schema/pagifier.cue

cue vet -d '#Project' pagifier.cue frontend/pagifier.yaml # project files
cue vet -d '#Root' pagifier.cue pagifier.yaml # root manifests

Both formats vet — cue vet reads the same files Pagifier does. It catches structural problems offline — unknown fields, enum violations, port ranges, non-ascending canary steps — before anything is uploaded. The server's POST /v1/validate remains the source of truth: it additionally resolves templates and enforces cross-field rules (for example, node requires a runtime command), so run both in CI: cue vet on every commit, /v1/validate on pull requests.

What Pagifier will never do

Detect frameworks · parse package.json, requirements.txt, or go.mod · guess ports · guess build commands · read a Dockerfile (you don't have one) · deploy anything not explicitly listed in a root manifest.