Skip to content

Infraspec Reference

The infraspec.yaml file is the single source of truth for an app's infrastructure requirements. Place it in the root of your project directory.

Complete example

yaml
app: mail-agent
role: webserver
port: 80
healthcheck: /health
hosts:
  external: mail.slopistry.com
  internal: mail-agent-service
build:
  dockerfile: Dockerfile
  test: npm test
services:
  postgres:
    database: mailagent_db
  kv:
    namespace: mail-agent
  events:
    topics: [mail.inbound, mail.processed]
secrets:
  - DATABASE_URL
  - SMTP_API_KEY
migrations:
  command: npm run db:migrate
  database: mailagent_db
artifacts:
  retain: 5
alerts:
  window: 5m
  threshold: 3

Field reference

Top-level fields

FieldTypeRequiredDefaultDescription
appstringYesUnique app identifier. Must match the directory name under NORN_APPS_DIR.
rolestringYesOne of webserver, worker, cron, function. Determines infrastructure behavior.
coreboolNofalseMarks the app as a Norn infrastructure component.
portintNoContainer port. Required for webserver role.
healthcheckstringNoHTTP path for health checks (e.g. /health).
replicasintNo1Number of pod replicas in the K8s Deployment.
schedulestringNoCron expression for cron role apps (e.g. "*/5 * * * *").
commandstringNoCommand to run in the container (used by cron apps).
runtimestringNo"docker"Container runtime: "docker" or "incus".
timeoutintNo300Max seconds per execution (cron apps).
deployboolNofalseMust be true for the app to appear in Norn.

hosts

Networking configuration for the app.

FieldTypeDescription
hosts.externalstringPublic hostname (e.g. mail.slopistry.com). Configures Cloudflare tunnel routing.
hosts.internalstringInternal K8s service name (e.g. mail-agent-service).

build

Build configuration for Docker images.

FieldTypeDescription
build.dockerfilestringPath to Dockerfile relative to app directory.
build.teststringTest command to run after build (e.g. npm test).

repo

Remote Git repository configuration. If set, Norn clones the repo during deploy instead of copying local files.

FieldTypeDefaultDescription
repo.urlstringGit clone URL (HTTPS or SSH).
repo.branchstring"main"Branch to clone.
repo.autoDeployboolfalseEnable webhook-triggered deploys.
repo.repoWebstringWeb URL for the repository (for UI links).
repo.webhookSecretstringShared secret for webhook verification. Not included in API responses.

services

Shared service dependencies. Each service is provisioned with per-app isolation.

services.postgres

FieldTypeDescription
services.postgres.databasestringDatabase name (e.g. mailagent_db).
services.postgres.migrationsstringMigration directory path.

services.kv

FieldTypeDescription
services.kv.namespacestringValkey key prefix namespace.

services.events

FieldTypeDescription
services.events.topicsstring[]Redpanda topic names.

services.storage

FieldTypeDescription
services.storage.bucketstringS3 bucket name.
services.storage.providerstringProvider hint: r2, s3, gcs, spaces.

secrets

A list of secret key names the app requires. Values are stored encrypted via SOPS + age in secrets.enc.yaml.

yaml
secrets:
  - DATABASE_URL
  - SMTP_API_KEY
  - WEBHOOK_SECRET

migrations

Database migration configuration.

FieldTypeDescription
migrations.commandstringShell command to run migrations (e.g. npm run db:migrate).
migrations.databasestringDatabase name for the migration target.

artifacts

FieldTypeDefaultDescription
artifacts.retainint5Number of Docker image tags to retain.

volumes

List of volume mounts for the K8s Deployment.

FieldTypeDescription
volumes[].namestringVolume identifier.
volumes[].mountPathstringContainer mount path.
volumes[].sizestringPVC size (e.g. 10Gi). Creates a PersistentVolumeClaim.
volumes[].hostPathstringHost directory path. Used instead of PVC when set.

env

Static environment variables injected into the K8s Deployment.

yaml
env:
  NORN_DATABASE_URL: "postgres://norn:norn@localhost:5432/norn_db?sslmode=disable"
  NORN_BIND_ADDR: "0.0.0.0"

alerts

Health check alert configuration.

FieldTypeDefaultDescription
alerts.windowstring"5m"Time window for counting failures.
alerts.thresholdint3Number of failures in window to trigger alert.

function

Function-specific configuration (only for role: function apps).

FieldTypeDefaultDescription
function.timeoutint30Maximum execution time in seconds.
function.triggerstring"http"Trigger type (currently only http).
function.memorystring"256m"Container memory limit.

Real example: Norn itself

Norn manages its own infrastructure via infraspec.yaml:

yaml
app: norn
role: webserver
core: true
port: 8800
healthcheck: /api/health
hosts:
  internal: norn-service
build:
  dockerfile: Dockerfile
artifacts:
  retain: 3
env:
  NORN_DATABASE_URL: "postgres://norn:norn@localhost:5432/norn_db?sslmode=disable"
  NORN_BIND_ADDR: "0.0.0.0"
  NORN_APPS_DIR: "/projects"
volumes:
  - name: projects
    mountPath: /projects
    hostPath: /Users/0xadb/projects

Interactive builder

Build an infraspec interactively and copy the result:

Configuration

Services

infraspec.yaml

app: my-app
role: webserver
port: 3000
healthcheck: /health
build:
  dockerfile: Dockerfile