Configuration (nexlayer.yaml)
The nexlayer.yaml file describes your entire deployment in a clean, readable format. Your AI assistant will generate this for you — but understanding it helps you customize and debug your deployments.
Designed to be Simple
Nexlayer's YAML format is intentionally minimal. No boilerplate, no repetition, no 500-line config files. Just describe your app and its services — Nexlayer handles the rest. This simplicity is core to how Nexlayer works with AI assistants.
Anatomy of a nexlayer.yaml
Every YAML has three main parts — think of them as building blocks:
Application Name
Your app's unique identifier. Add a url field for production deployments.
Pods (Services)
Your app's containers — frontend, API, database, etc. Each pod runs independently and can communicate with others.
Configuration
Ports, environment variables, persistent storage, and URL paths for each service.
application:
name: my-app # Your app's unique name
url: www.mysite.com # Optional: for production deployment
pods:
- name: web # Service name
image: nginx:latest # Docker image to run
path: / # URL path (/ = homepage)
servicePorts: [80] # Port(s) your app listens onKey Concepts
Pods
Think of pods as individual services. A typical app might have a frontend pod, an API pod, and a database pod. Pods communicate using internal DNS:podname.pod
Images
Docker images from Docker Hub (public) or GitHub Container Registry (private with auth). Your AI assistant can help you build and push images.
Paths
URL routes for each service. path: / handles the homepage, path: /api handles API endpoints.
Volumes
Persistent storage that survives restarts. Essential for databases and file uploads. Specify size and mount path. Any pod with a volumes entry is automatically upgraded to a StatefulSet, whether or not resourceType is set.
Secrets
Sensitive values stored securely by Nexlayer. Injected as environment variables (default) or mounted as read-only files. Manage via the dashboard or the secrets field in your YAML.
nexlayer.yaml v2.0
Newv2.0 adds workload types beyond the default deployment — StatefulSets, DaemonSets, Jobs, and CronJobs — plus resource requests/limits and subdomain routing.
Opt in to v2.0
Every field below is inactive until you set application.version: 2.0, placed above name. Using a v2 field without it doesn't error — Nexlayer silently ignores the field and warns you to add the version.
application:
version: 2.0 # Must come above name. Accepts a number or numeric string: 2, 2.0, "2.0"
name: my-appresourceType
Sets the workload type for a pod. Defaults to deployment when omitted.
| Value | Use case |
|---|---|
deployment (default) | Stateless — replicas are interchangeable |
statefulset | Stable identity + durable per-instance storage — Postgres, MySQL, Mongo, Redis cluster, Kafka |
daemonset | One pod per node — log shippers, metrics collectors, network sidecars |
job | Runs to completion, no restart on success — migrations, seeding, backups |
cronjob | Runs to completion on a recurring schedule — requires schedule |
pods:
- name: postgres
resourceType: statefulset
image: postgres:15
servicePorts: [5432]schedule
Required when resourceType: cronjob, ignored otherwise. Accepts a 5-field cron expression (0 3 * * *) or a macro: @yearly, @annually, @monthly, @weekly, @daily, @midnight, or @hourly.
pods:
- name: db-backup
resourceType: cronjob
schedule: "0 3 * * *" # or "@daily"
image: myuser/db-backup:latestreplicas
Integer ≥ 1, defaults to 1. Horizontal scaling for stateless pods only — stateful pods should stay at 1 unless the workload itself is clustering-aware. See Scaling.
pods:
- name: api
resourceType: deployment
replicas: 3resources
CPU and memory requests and limits.
resources:
requests:
cpu: 500m # or whole cores: "1", "2"
memory: 512Mi # Ki/Mi/Gi/Ti or K/M/G/T
limits:
cpu: 2
memory: 1GiValidation error: a limit set below its matching request is rejected, not just warned.
subdomain
DNS label(s) Nexlayer prepends to your deployment's domain to route to this pod. Requires application.url (a custom domain) — it has no meaning on a preview deployment. Accepts a single label or a dotted multi-label hostname.
application:
version: 2.0
name: my-app
url: mysite.com
pods:
- name: api
subdomain: api # → api.mysite.com
- name: admin
subdomain: admin.internal # → admin.internal.mysite.comWhat validation changed
- •
servicePortsis optional forjobandcronjobpods — still required for every other pod. - •At least one pod must have a
path, except when every pod in the manifest isjob/cronjob(pure batch/cron manifests need no path). - •
subdomainwithoutapplication.urlis a validation error. - •
application.versionmust be a number or numeric string (2,2.0,"2.0") — anything else is rejected. - •Using any v2 field (
resourceType,replicas,resources,subdomain,schedule) withoutversion: 2.0set produces a warning, not an error — the field is silently ignored.
Automatic upgrade: any pod that includes a volumes entry is automatically upgraded to resourceType: statefulset, whether or not you set it explicitly — durable storage needs a stable pod identity.
Example Configurations
Simple Website
A static website or simple web app — the simplest possible deployment.
application:
name: my-website
url: www.mysite.com # Remove for preview deployment
pods:
- name: web
image: nginx:latest
path: /
servicePorts: [80]PERN Stack
PostgreSQL + Express + React + Node.js — a full-stack app with database, API, and frontend.
application:
name: pern-app
pods:
# Database
- name: postgres
image: postgres:15
servicePorts: [5432]
vars:
POSTGRES_USER: postgres
POSTGRES_PASSWORD: secretpassword
POSTGRES_DB: myapp
volumes:
- name: pg-data
size: 2Gi
mountPath: /var/lib/postgresql/data
# API
- name: express
image: myuser/express-api:latest
path: /api
servicePorts: [3000]
vars:
DATABASE_URL: postgresql://postgres:secretpassword@postgres.pod:5432/myapp
# Frontend
- name: react
image: myuser/react-app:latest
path: /
servicePorts: [80]
vars:
API_URL: http://express.pod:3000Notice how services reference each other using postgres.pod and express.pod.
Next.js Full-Stack
Next.js with PostgreSQL and Drizzle ORM — modern full-stack with persistent data.
application:
name: nextjs-app
pods:
# Next.js Frontend + API
- name: nextjs
image: myuser/nextjs-app:latest
path: /
servicePorts: [3000]
vars:
DATABASE_URL: postgresql://postgres:password@postgres.pod:5432/mydb
# PostgreSQL Database
- name: postgres
image: postgres:15
servicePorts: [5432]
vars:
POSTGRES_USER: postgres
POSTGRES_PASSWORD: password
POSTGRES_DB: mydb
volumes:
- name: postgres-data
size: 1Gi
mountPath: /var/lib/postgresql/dataPostgres + Nightly Backup (v2.0)
A StatefulSet database, a scheduled backup CronJob, and a subdomain-routed API — using v2.0's resourceType, resources, schedule, and subdomain fields.
application:
version: 2.0
name: my-app
url: mysite.com
pods:
# Database — auto-upgraded to statefulset because of volumes,
# set explicitly here for clarity
- name: postgres
resourceType: statefulset
image: postgres:15
servicePorts: [5432]
resources:
requests:
cpu: 500m
memory: 512Mi
limits:
cpu: 2
memory: 2Gi
vars:
POSTGRES_USER: postgres
POSTGRES_PASSWORD: secretpassword
POSTGRES_DB: myapp
PGDATA: /var/lib/postgresql/data/pgdata
volumes:
- name: pg-data
size: 10Gi
mountPath: /var/lib/postgresql/data
# Nightly backup — no servicePorts or path needed
- name: db-backup
resourceType: cronjob
schedule: "@daily"
image: myuser/db-backup:latest
vars:
DATABASE_URL: postgresql://postgres:secretpassword@postgres.pod:5432/myapp
# API — routed at api.mysite.com
- name: api
replicas: 2
path: /
servicePorts: [3000]
subdomain: api
image: myuser/api:latest
vars:
DATABASE_URL: postgresql://postgres:secretpassword@postgres.pod:5432/myappPGDATA points Postgres at a subdirectory of the mount instead of its root — the mount root can contain reserved entries (like lost+found) that block Postgres from initializing there directly.
Service Discovery
Pods can communicate with each other using internal DNS. The format is simple:
# Format: <pod-name>.pod:<port>
# Examples:
DATABASE_URL: postgresql://user:pass@postgres.pod:5432/db
API_URL: http://express.pod:3000
REDIS_URL: redis://redis.pod:6379Let Your AI Assistant Handle It
You don't need to memorize this. Just tell your AI assistant what you want to deploy:
"Deploy this Next.js app with a PostgreSQL database. I need the data to persist."
Your assistant will generate the YAML, help you build the Docker images, and deploy everything to Nexlayer.