Skip to content
Guides

Deploy a Next.js app

From a GitHub repository to a live Next.js app on its own address: the Node.js version, variables built into the app, a database and your domain.

Updated 17 Oct 20264 min read

Asha's shop is getting a new storefront in Next.js, in the repository asha/duka-store. This guide puts it live in project duka, next to her Laravel app, in about ten minutes. Next.js runs as it does on your computer: next build, then next start.

Step 1: check your package.json

A standard Next.js app deploys as it is. Its package.json needs the two usual scripts:

json
{
  "scripts": {
    "dev": "next dev",
    "build": "next build",
    "start": "next start"
  }
}

We run npm run start, and next start listens on the port in the PORT variable (8080 here) on every address, as Next.js does by default. Commit your lock file (package-lock.json, pnpm-lock.yaml or yarn.lock): we pick the same tool, so the build installs exactly what you tested.

Step 2: choose the Node.js version

We offer Node.js 22 and 24. Name yours in a .nvmrc file at the top of your repository, with just the version in it:

Terminal
24

Without one, we use the newest we offer.

Step 3: add the app

  1. Open your project. In the Add a service card, choose App.

  2. Under Where's your code?, choose GitHub, pick asha/duka-store and the Branch main, and leave Build every time I push on.

  3. We show what we found: Next.js, with npm. Name the app storereading today's prices

  4. Choose Deploy.

The build runs npm ci --include=dev, then npm run build, with NODE_ENV=production, and the log shows each line as it happens. A new version gets visitors only once / answers with a success, within 2 minutes, so a broken build never takes the store down.

Until GitHub is switched on

Connecting GitHub needs our GitHub app, which isn't set up yet, and the GitHub tab says so. Meanwhile, download your repository as a ZIP and choose Upload a ZIP instead.

Step 4: add your variables

Open the project's Variables tab and choose store. Add your settings one by one, or choose Paste a .env file and paste your .env.local:

Terminal
NEXT_PUBLIC_SHOP_NAME=Duka
STRIPE_SECRET_KEY=…

Variables starting with NEXT_PUBLIC_ are written into the browser's code when Next.js builds, so builds get your variables too. After you change one of those, build again: open the app and, in its Code card, choose Build again. The others, used only on the server, take effect with Redeploy.

Step 5: connect a database, if you use one

Add PostgreSQL to the project and tick store, and the app gets DATABASE_URL (through connection pooling) and DATABASE_DIRECT_URL (straight to the database). Prisma, Drizzle and most libraries read DATABASE_URL as it is:

js
import postgres from "postgres";

const sql = postgres(process.env.DATABASE_URL);

Run migrations before each new version goes live: open the app and, under Build and run, set Before going live to your migrate command, like npx prisma migrate deploy. If it fails, the version before keeps serving. Tools that need one connection for a whole session, as some migration tools do, can use DATABASE_DIRECT_URL. See PostgreSQL.

Step 6: your domain

Your store is live on its free address, like store-duka-k2m9.tanzahost.co. To put it on shop.duka.co.tz, open the project's Domains tab and add it. See Add a domain. SSL is issued by itself once the records are right.

What to know about Next.js here

TopicOn Tanzahost
Static filesThe files Next.js builds under /_next/static/ are kept at our door, close to your visitors, for up to a day, and forgotten on each deploy.
PagesEvery page is answered by your app: the door keeps only static files, like images, styles, scripts and fonts.
Your app's filesYour code is read-only while it runs. Write uploads to a storage service or a database, not to the app's folders.
Memory for the build2 GB, or your app's memory limit if higher. A big build that runs out: see JavaScript heap out of memory.
Background jobsA queue consumer runs as a worker, with its own command.
Jobs on a timetableA scheduled task, like npm run cleanup every night. Times are in UTC.
Next.js's own cache

Next.js keeps regenerated pages (ISR) and resized images in .next/cache. Because your code is read-only while it runs, it can't keep new files there between visits. Pages built at build time are fine; pages and images Next.js makes while running are made again instead of kept. Set images.unoptimized in next.config if you resize images elsewhere.