DeployxaDocs Portal
CLI v1.0.4
Deploy Next.js App (App Router)
Framework guide · Next.js

Deploy a Next.js app (App Router)

Next.js runs on Deployxa as a long-lived Node.js server, so the App Router, Server Components, Server Actions, route handlers, ISR and middleware behave the way they do with next start locally. There is no per-request function timeout.

Prerequisites

  • A Next.js 14 or newer project with build and start scripts in package.json.
  • A committed lockfile (package-lock.json, pnpm-lock.yaml, yarn.lock or bun.lockb); it decides the package manager.
  • A Deployxa account, and either a GitHub repository or the CLI (npm install -g @deployxa/cli).

How Deployxa detects Next.js

A next dependency in package.json (or a next.config.* file) selects the Next.js preset on Node.js 20. These are the defaults; every one can be overridden.

SettingValue
Build commandnpm run build
Start commandnpm run start
Output directory.next
Port3000
RuntimeNode.js 20 LTS

With pnpm, yarn or bun the same scripts run through that package manager.

The default preset works with a stock project. For a smaller runtime, enable standalone output, which traces only the files the server needs into .next/standalone:

ts
// next.config.ts
import type { NextConfig } from 'next';

const nextConfig: NextConfig = {
  output: 'standalone',
};

export default nextConfig;

Standalone output does not include public/ or .next/static, and next start does not serve a standalone build. Copy the assets in the build script and change the start command:

json
{
  "scripts": {
    "build": "next build && cp -r public .next/standalone/ && cp -r .next/static .next/standalone/.next/",
    "start": "node .next/standalone/server.js"
  }
}
Warning: The standalone server.js binds to HOSTNAME. Inside a container that variable holds the container ID, so set HOSTNAME=0.0.0.0 as an environment variable, or the health check cannot reach the server. It reads PORT too (default 3000).

Environment variables

KeyPurposeExample
NODE_ENVRuntime modeproduction
NEXT_PUBLIC_API_URLPublic value inlined into the browser bundle at build timehttps://api.example.com
DATABASE_URLInjected when you attach a database; read by Prisma, Drizzle or pgpostgresql://…
HOSTNAMEBind address for standalone server.js0.0.0.0

NEXT_PUBLIC_* values are baked in during next build, so change them and redeploy. Server-only values are read at runtime. See Environment variables.

Databases

In the wizard's Configure step, set Database to PostgreSQL. The connection string is injected into the app as DATABASE_URL, so nothing needs to be committed. Choose SQLite only for small apps: it lives on a persistent volume and has no server.

With Prisma, run prisma generate during the build (add "postinstall": "prisma generate") and apply migrations before the server starts: add "start:prod": "prisma migrate deploy && next start" to package.json and set the start command to npm run start:prod. Keep prisma in dependencies so the CLI exists at runtime.

Deploy

From the dashboard

  1. 1
    Source

    Open Dashboard → Projects → New project (/dashboard/projects/new). Pick the GitHub repository and branch, or upload a .zip archive of the project.

  2. 2
    Configure

    Leave the framework preset on Auto-detect or choose Next.js. Check the fields under advanced settings:

    • Build command: npm run build
    • Output directory: .next
    • Root directory: ./, or the sub-folder that holds the app in a monorepo
    • Database: PostgreSQL if the app needs one
  3. 3
    Environment

    Add your variables in the table, or paste a whole .env file into the Bulk / .env tab.

  4. 4
    Deploy

    Start the deploy and watch the build log. When the release passes its health check it is served over HTTPS on its Deployxa URL.

  5. 5
    Confirm the start command and port

    Open the project's Environment Canvas tab and select the web service. Set Start Command to npm run start. Set Internal Port to 3000 so it matches the port your app listens on. Save and redeploy if you changed anything.

From the CLI

shell
$ npm install -g @deployxa/cli
$ deployxa login
$ cd my-app
$ deployxa link            # pick an existing project, or skip: deploy creates one
$ deployxa env set NEXT_PUBLIC_API_URL "https://api.example.com"
$ deployxa deploy
$ deployxa logs --live     # stream build and runtime logs
$ deployxa open            # open the live URL

If the folder is not linked, deployxa deploy creates a project named after the folder and links it (the link is saved in .deployxa/config.json). Later runs deploy the linked project. deployxa status shows the latest deployment and deployxa rollback previous returns to the release before it.

Warning: deployxa deploy packages the folder exactly as it is on disk; it does not read .gitignore. Delete local node_modules, virtualenvs, build output and real .env files first, or deploy from a clean clone. Set secrets with deployxa env set instead of shipping them in the archive.

Custom domain

Go to Dashboard → Domains, choose Connect a domain you already own and pick this project. Deployxa then shows the DNS records to create at your DNS provider:

RecordUse it forValue
AAn apex domain such as example.com85.17.244.184 (DNS only on Cloudflare)
CNAMEA subdomain such as www or appcname.deployxa.com (DNS only on Cloudflare)
TXTOnly when a CDN or proxy (for example Cloudflare orange-cloud) hides the origin recordHost _deployxa-challenge.<your-domain>, value deployxa-verification=…

DNS changes can take several minutes to propagate; use Retry verification once they have. A Let's Encrypt certificate is issued after the domain verifies. From a linked folder you can do the same with the CLI:

shell
$ deployxa domains add app.example.com
$ deployxa dns             # Waiting → Verified → SSL Active
$ deployxa domains list

Common errors and fixes

SymptomFix
Build fails with "Type error" or ESLint errorsFix them locally with npm run build; the build runs the same type check.
Health check fails, logs show the server listening on a container IDStandalone mode: set HOSTNAME=0.0.0.0.
"next start" does not work with "output: standalone"Change the start command to node .next/standalone/server.js.
CSS, images or /_next/static return 404 in standalone modeCopy public and .next/static into .next/standalone in the build script.
A NEXT_PUBLIC_ value is stale or undefinedIt was missing at build time. Set it, then redeploy so the bundle is rebuilt.
App crashes with "Cannot find module"A runtime package is in devDependencies; move it to dependencies.

Start with deployxa logs --live (or the deployment's log view in the dashboard): the build log shows dependency and compile failures, the runtime log shows crashes and bind errors. See also Troubleshooting.