Build
Deploy a Next.js app on Aria
A complete aria.yaml for a Next.js app with Postgres: build-time variables, migrations, health check, domain, and the commands to deploy and check it.
In this page
To deploy a Next.js app on Aria, describe it as one web service in aria.yaml, add a Postgres database, wire DATABASE_URL with from: main.url, and mark any NEXT_PUBLIC_ variable your build reads. Aria then builds the app, runs your migration command, starts it and checks that it answers. Next.js runs as an ordinary long-running Node server on your own VPS.
What does the stack file look like?
version: 1
name: my-next-app
services:
web:
type: web
framework: nextjs
install: npm ci
build: npm run build
start: npm start
port: 3000
healthcheck: /api/health
migrate: npx prisma migrate deploy
domain: "@"
databases:
main:
type: postgres
env:
DATABASE_URL:
services: [web]
from: main.url
AUTH_SECRET:
services: [web]
generate: secret
NEXT_PUBLIC_SITE_NAME:
services: [web]
value: My app
build: true
STRIPE_SECRET_KEY:
services: [web]
required: true
secret: true
description: Stripe secret key, from the Stripe dashboard
resources:
users: 200Swap npx prisma migrate deploy for your own migration command, or remove migrate if your app creates tables another way. Every field is explained in the aria.yaml reference.
What does each part do?
framework: nextjsis a hint for sizing. A Next.js build needs more memory than a small API, and Aria counts that when it suggests a plan.install,buildandstartrun when there is no Dockerfile. Each is one line.port: 3000is the port Aria routes to. Aria setsPORTto it, andnext startreads it and listens on all interfaces by default.healthcheckis a path your app answers quickly with a 2xx and no login. Create a route at/api/healththat returns “ok”, or use/if your home page is public.migrateruns once per deploy, in the newly built image, before the new version takes traffic. If it fails, the old version keeps serving.domain: "@"asks for your main domain when you connect one. See Domains.NEXT_PUBLIC_SITE_NAMEis read while the app builds, so it needsbuild: true. Names that start withNEXT_PUBLIC_are passed at build time automatically, and anyone who visits the site can read them. Never wire a secret into one.STRIPE_SECRET_KEYisrequiredandsecret. The service waits until you enter it witharia env add STRIPE_SECRET_KEY. See Environment variables.
Can I use a Dockerfile instead?
Yes. Set dockerfile and Aria ignores install, build and start. Declare every variable the build reads with ARG:
FROM node:22-alpine
WORKDIR /app
ARG NEXT_PUBLIC_SITE_NAME
COPY package*.json ./
RUN npm ci
COPY . .
RUN npm run build
ENV NODE_ENV=production
CMD ["npm", "start"]services:
web:
type: web
dockerfile: Dockerfile
port: 3000
healthcheck: /api/healthWhat if my app is in a monorepo?
Set path to the app’s folder and context to the root of the workspace, so the build can see shared packages. The commands then run from that root:
services:
web:
type: web
path: apps/web
context: .
build: pnpm install --frozen-lockfile && pnpm --filter web... build
start: pnpm --filter web start
port: 3000A push rebuilds a service only when files under its path change, plus the root files such as the lockfile when context is .. Code in a shared package outside every service’s path rebuilds nothing, so run aria deploy after changing it. A monorepo build needs more memory, and Aria counts that too.
Are there more examples?
Two whole stacks are written out in the aria.yaml reference: a three-service stack with Postgres and Redis, and a web app on self-hosted Supabase, which passes NEXT_PUBLIC_ variables into a Dockerfile build.
How do I deploy it?
Aria AI can write the file for you during setup. Otherwise commit aria.yaml and push. Once the app is live, a push redeploys the services that the commit touched. For the first launch, or to apply a changed aria.yaml that you did not push:
aria deploy --wait
aria check
aria openaria deploy web deploys one service. If something fails, aria logs web --lines 200 shows its recent output.
Which plan do I need?
Aria estimates your stack’s memory from aria.yaml and recommends the smallest plan that fits, with room for builds. For the file above, with Postgres, the estimate is about 4.0 GB, which just fits the Starter plan. Add Redis and it is about 4.2 GB, which needs Developer. The plan table is on the billing page, and prices are on pricing.
For the reasoning behind running Next.js on your own server, read Deploy Next.js on your own server. If your app came from an AI builder, read Deploy a vibe-coded app.