Skip to main content
This tutorial takes a Next.js app from a git repository to a domain on your own server. It builds with Railpack, which is the default for a Next.js repository, and it ends with a rollback you can run in one command. For the full reference on Next.js, including the Dockerfile route and the static export, see Self-host Next.js and Frameworks. Performance numbers are pending a host run. The sizing guidance in Build performance is arithmetic from assumed memory per site, not a measurement.

Before you start

  • A running Levelrail instance and the CLI logged in to it (installing).
  • A Next.js app in a git repository that your server can clone. The app must start with npm run start after npm run build, which is the Railpack default.
  • A domain name you control, pointed at the server. See Domains and ingress.
  • A server with at least 2 GB of RAM for a build. Building on a 1 GB host is not recommended. See Build performance.

Step 1: Create the app from the repository

Pick the port Next.js listens on. The default is 3000, and next start uses it unless PORT is set.
The dry run prints the plan without creating anything. Read it, then run the same command without --dry-run:
Levelrail detects the Next.js framework, builds it with Railpack and starts it with npm run start. The build log says which framework it chose.

Step 2: Set the public environment before the first build

Next.js inlines NEXT_PUBLIC_* values at next build, so a value set after the first build does not reach the browser until the next build. Add those values as plain app environment variables in the dashboard, on the app’s Environment card, before you deploy. Do not put them in the secrets store, because secrets are never passed to a build. Server-only values, such as a database URL, go in the same card as secrets. A database connection is covered in Connect an app to Postgres.

Step 3: Set a health check

The health check decides whether a new release replaces the old one. For a Next.js app, / is a reasonable first check, but a route that does not touch the database is better, so a slow database does not block every deploy.
Readiness gates the switch to a new release. Read Zero-downtime deploys with health checks for what a failed check looks like.

Step 4: Check the deploy

Open https://web.example.com in a browser. The page should load with a valid certificate. If the certificate is not issued yet, the status shows the reason, and Domains and ingress explains the HTTP-01 and DNS-01 options.

Step 5: Ship a second version and roll back

Push a change to the branch, or redeploy the same branch:
rollback puts back the previous release. Check the page again. Whether a rollback rebuilds the image is pending run.

Troubleshooting

  • The build runs out of memory (exit 137). The build hit its memory cap. Raise the build limit for the app, or add swap on the server. The build log names the setting. See Build performance.
  • The page is blank or shows old NEXT_PUBLIC_ values. The variable was added after the build. Redeploy so next build runs again.
  • The health check fails right after deploy. Raise the readiness timeout, or check that the app listens on the port you set in Step 1.

Where to go next

Last modified on November 2, 2026