Deploy a Next.js app

Full-stack Next.js — pages, API routes, and server rendering — on a live HTTPS URL.

Dockhold runs Next.js as a real Node server, so server components, API routes, and server-side rendering all work — you don't have to flatten the app to a static export. This recipe is the whole path.

In a hurry? Start from the ready-made nextjs-starter template — click Use this template on GitHub, then deploy it. Or follow the steps below to set up a project you already have.

1. Bind next start to the assigned port

Make the start script use $PORT and bind all interfaces. In package.json:

{
  "scripts": {
    "build": "next build",
    "start": "next start -H 0.0.0.0 -p $PORT"
  }
}

Your app must listen on 0.0.0.0 and read its port from the PORT environment variable — never localhost, never a hardcoded port. Dockhold assigns PORT at runtime; an app that ignores it can't receive traffic.

Don't set output: 'export' in next.config.js unless you specifically want a static-only build — it disables API routes and server rendering. For a normal Next.js app, leave it off.

2. Connect the repo and deploy

  1. Push the project to a GitHub repository.
  2. Open the dashboard, connect GitHub, and pick the repo.
  3. Dockhold detects Next.js, runs npm install and npm run build, then starts it with npm run start. No Dockerfile needed.

Your app goes live at https://<your-app>.dockhold.app with HTTPS handled for you. Every later push to your main branch redeploys.

3. Environment variables

Set variables in the dashboard — Dockhold doesn't read a committed .env. Server-side code reads them from process.env at runtime (route handlers, server components, getServerSideProps); keep API keys and tokens in the Vault. Variables that reach the browser need the NEXT_PUBLIC_ prefix and are baked in when the app is built — and the build doesn't see your dashboard variables, so set those in code (e.g. next.config.js), for public values only, never a secret.

4. Add a database (optional)

Enable the managed Postgres add-on and Dockhold injects DATABASE_URL into your app. Read it from process.env.DATABASE_URL in server code — don't run your own database, and don't commit a connection string.

Troubleshooting

  • App builds but the URL times out: the start script must include -H 0.0.0.0 -p $PORT. A default next start may bind the wrong host or port.
  • API routes 404 in production: check you haven't enabled output: 'export' — static export drops the server.
  • A public env var is undefined: it must be prefixed NEXT_PUBLIC_ and set in code — the build can't read dashboard variables.

Next