Deploy Next.js with Postgres and Prisma

This guide deploys a Next.js App Router app to Naijacloud with a managed Postgres database. At the end you’ll have a small notes app at your own naijacloud.app address that saves to Postgres through Prisma, with migrations applied every time a new version starts and every push to your branch deploying automatically. The stack is Next.js 16, Prisma 7 with the pg driver adapter, and Postgres 18, deployed from a GitHub repository.

15 minBeginnerLast verified 2026-10-11nextjsprismapostgres
What you'll have at the end

A Next.js notes app on your own naijacloud.app address. Type a note, press Save, and it’s written to Postgres and read back on every request.

Deploy this templateNext.js starter template

Before you start

  • A Next.js app in a GitHub repository, with its package-lock.json committed. Starting fresh? Run npx create-next-app@latest and push it.
  • Node.js 20 or newer on your machine, and Docker if you want a Postgres to develop against.
  • A Naijacloud account. The free tier covers this guide: one web service and one database.

Add Prisma

Install the Prisma CLI, the client and the driver adapter for pg. Prisma 7 talks to Postgres through the adapter rather than its own engine.

Terminal
$ npm install @prisma/client@7 @prisma/adapter-pg@7
$ npm install --save-dev prisma@7

Create the schema. The client is generated into app/generated/prisma, so add that folder to .gitignore: it’s rebuilt on every build.

prisma/schema.prisma
generator client {
provider = "prisma-client"
output = "../app/generated/prisma"
}
datasource db {
provider = "postgresql"
}
model Note {
id Int @id @default(autoincrement())
body String
createdAt DateTime @default(now())
}

Prisma 7 reads the connection string from prisma.config.ts, not from the schema:

prisma.config.ts
import { defineConfig } from "prisma/config";
export default defineConfig({
schema: "prisma/schema.prisma",
migrations: { path: "prisma/migrations" },
datasource: { url: process.env.DATABASE_URL },
});

Create the first migration

Run a Postgres locally and create the migration against it. The migration files are what Naijacloud applies to the real database later, so commit them.

Terminal
$ docker run -d --name notes-db -p 5432:5432 -e POSTGRES_PASSWORD=pw -e POSTGRES_DB=notes postgres:18-alpine
$ export DATABASE_URL=postgresql://postgres:pw@localhost:5432/notes
$ npx prisma migrate dev --name init

Then make npm run build generate the client before Next.js builds, in package.json:

package.json
"scripts": {
"dev": "next dev",
"build": "prisma generate && next build",
"start": "next start"
}

Read and write from a page

Create one Prisma client for the whole process:

lib/db.ts
import { PrismaPg } from "@prisma/adapter-pg";
import { PrismaClient } from "@/app/generated/prisma/client";
const globalForPrisma = globalThis as unknown as { prisma?: PrismaClient };
export const prisma =
globalForPrisma.prisma ??
new PrismaClient({
adapter: new PrismaPg({ connectionString: process.env.DATABASE_URL }),
});
if (process.env.NODE_ENV !== "production") globalForPrisma.prisma = prisma;

Then a page that lists notes and saves new ones with a server action. await connection() keeps the query at request time, so the build never needs the database.

app/page.tsx
import { revalidatePath } from "next/cache";
import { connection } from "next/server";
import { Suspense } from "react";
import { prisma } from "@/lib/db";
async function addNote(formData: FormData) {
"use server";
const body = String(formData.get("body") ?? "").trim();
if (body) await prisma.note.create({ data: { body } });
revalidatePath("/");
}
async function Notes() {
// Read the database on every request, never at build time.
await connection();
const notes = await prisma.note.findMany({ orderBy: { createdAt: "desc" } });
return (
<ul>
{notes.map((note) => (
<li key={note.id}>{note.body}</li>
))}
</ul>
);
}
export default function Home() {
return (
<main>
<h1>Notes</h1>
<form action={addNote}>
<input name="body" placeholder="Write a note" />
<button type="submit">Save</button>
</form>
<Suspense fallback={<p>Loading…</p>}>
<Notes />
</Suspense>
</main>
);
}
Terminal
$ git add .
$ git commit -m "Notes on Postgres with Prisma"
$ git push

Create the database

In the dashboard, open your project and choose New service → Database. Name it notes-db, pick Postgres, choose the Free size and click Create database. On the notes-db is ready. screen, click Reveal secrets and copy the Internal URL. The password is shown once on this page.

Create the web service

Choose New service → Web service, name it notes and, under Source, pick your repository and branch on the GitHub tab. Naijacloud detects Next.js and fills in npm ci && npm run build and npm start. Keep the build command and change the start command so migrations run first:

Build commandnpm ci && npm run build
Start commandnpx prisma migrate deploy && npm start

Under Environment variables, click + Add variable and add one:

DATABASE_URLThe Internal URL you copied from the database

Leave the size on Free and click Create web service. Free apps may sleep when nobody visits for a while and wake on the next request; paid apps never sleep.

Deploy and try it

Open the service. The Deploys tab streams the build; when it goes live, the runtime log shows the migration and Next.js starting:

Runtime log · notes
Applying migration `20261007033409_init`
All migrations have been successfully applied.
> next start
▲ Next.js 16.4.0
✓ Ready in 55ms

Open https://notes.naijacloud.app, write a note and press Save. It’s in Postgres: reload the page and it’s still there. Every push to your branch now builds, migrates and goes live.

Whatever you build it with, it ships here.

Deploy your app for free

Free tier forever · No card