SaaS

Deploy Next.js with Prisma and Postgres on DigitalOcean App Platform

We earn commissions when you shop through the links below.

Run a Next.js + Prisma app on DigitalOcean App Platform: App Platform vs a Droplet, current pricing, a dev vs managed Postgres database, the DATABASE_URL bindable variable, and migrations in a pre-deploy job.

8 min read

Disclosure: the DigitalOcean App Platform and Managed PostgreSQL product links in this article are affiliate links. If you sign up through one and become a paying customer, Designyff may earn a commission. The DigitalOcean documentation and pricing links, and every other link, are ordinary links. Nothing here was paid for by DigitalOcean.

DigitalOcean gives you two ways to run a Next.js app: a Droplet, which is a Linux server you manage, or App Platform, which builds your repo and runs it for you. This guide is about App Platform with Prisma and Postgres. It covers the settings that decide whether the deploy works: the build and run commands, the database you attach, the DATABASE_URL bindable variable, and where prisma migrate deploy runs. It also covers what it costs.

If you already know you want this setup, start with DigitalOcean App Platform.

App Platform or a Droplet

Both run the same Next.js server. The difference is who owns the machine.

  • App Platform builds from GitHub, GitLab, Bitbucket, or a container registry, and handles HTTPS, OS patching, and rollbacks. You choose a container size per component. You never SSH in.
  • A Droplet is a VPS. You install Docker, set up TLS, patch the OS, and run backups yourself. In return you get the whole server for a fixed price and can run anything on it. Self-hosting Next.js on a VPS with Docker walks through that setup step by step.

Pick App Platform when you would rather pay a little more per unit of RAM than own a server. Pick a Droplet when you are comfortable with SSH and want several services on one box. If you are comparing App Platform with other managed hosts, deploying the same stack on Railway uses the same standalone build and migration pattern.

App Platform pricing for a Next.js app (as of 12 October 2026)

These numbers are from DigitalOcean’s App Platform pricing and Managed Databases pricing pages. Check them before you rely on them, because they change.

The free tier covers up to 3 apps that only contain static sites. A Next.js server is a web service, so it needs a paid container:

ContainervCPUMemoryOutbound transferAutoscalingPer month
Shared, fixed1512 MiB50 GiBNo$5
Shared, fixed11 GiB100 GiBNo$10
Shared11 GiB150 GiBNo$12
Shared12 GiB200 GiBNo$25
Shared24 GiB250 GiBNo$50

A fixed container limits that component to a single instance. Autoscaling is only available on dedicated containers. Outbound transfer above the allowance is $0.02 per GiB.

For the database you have two choices:

DatabasePer monthWhat you get
Dev database (PostgreSQL)$7512 MiB RAM, usable only from its app, not backed up by default, destroyed with the app
Managed PostgreSQL, smallest plan$15.151 GiB RAM, 1 vCPU, 10 GiB storage (expandable)

So a small production setup is roughly one $10 to $12 container plus a $15.15 managed database. A Next.js server with 512 MiB of RAM can work for a small app, but leave headroom: Next.js and Prisma together are not tiny.

Dev database or managed database

The dev database is fine for a preview app or a demo. DigitalOcean’s own description is the reason not to put customers in it: it is not backed up by default, and it disappears if you delete the app. For anything that takes payments, use DigitalOcean Managed PostgreSQL and attach it to the app. The app spec reference says cluster_name is required for production databases, which is what ties the app to that cluster.

Step 1: Build Next.js for App Platform

App Platform detects a Node.js app from package.json and builds it with the Node.js buildpack. It runs your build script by default and uses Node.js 22.x unless you pin a version in engines. Pin it, so a platform default change does not change your runtime:

{
  "engines": { "node": "22.x" },
  "scripts": {
    "build": "prisma generate && next build",
    "start": "next start"
  }
}

prisma generate in the build makes sure the Prisma Client that ships matches your schema.

The service listens on its http_port, which defaults to 8080. If you do not set a PORT variable, App Platform adds one with that value. next start reads PORT, so this works without changes.

You do not need output: "standalone" for the buildpack. If you would rather control the image, add a Dockerfile and set dockerfile_path in the app spec. The standalone setup from the VPS guide works on App Platform too, including copying public and .next/static into the image.

NEXT_PUBLIC_ variables are build-time values. Next.js inlines them when it builds. On App Platform, give those variables the BUILD_TIME or RUN_AND_BUILD_TIME scope. Secrets such as STRIPE_SECRET_KEY and AUTH_SECRET should be RUN_TIME and type SECRET.

Step 2: Attach Postgres and bind DATABASE_URL

Add the database in the app: Add resource → Database, then either create a dev database or attach an existing managed cluster. When you attach a managed cluster with trusted sources enabled, the app is added as a trusted source, so only the app can connect.

Do not paste a connection string into your service. Use a bindable variable instead. If the database component is named db:

services:
  - name: web
    envs:
      - key: DATABASE_URL
        scope: RUN_TIME
        value: ${db.DATABASE_URL}

App Platform fills in the value at runtime. If the app and the database are in the same VPC, ${db.DATABASE_PRIVATE_URL} uses the private network instead of the public endpoint. ${db.CA_CERT} holds the cluster’s CA certificate if your database client needs it to verify TLS. See environment variables for the full list.

Your Prisma schema does not change:

datasource db {
  provider = "postgresql"
  url      = env("DATABASE_URL")
}

If you started on the Next.js SaaS Boilerplate, its schema uses SQLite. Switch provider to postgresql first. A SQLite file on a container disk is not a production database.

Step 3: Run prisma migrate deploy in a pre-deploy job

This is the step that most often breaks. DigitalOcean’s database docs state that App Platform does not support connecting to managed databases with trusted sources enabled during the build. So do not run migrations in your build script. Run them in a job with kind: PRE_DEPLOY, which runs before the new version of the app is deployed:

jobs:
  - name: migrate
    kind: PRE_DEPLOY
    github:
      repo: your-org/your-app
      branch: main
      deploy_on_push: true
    environment_slug: node-js
    run_command: npx prisma migrate deploy
    envs:
      - key: DATABASE_URL
        scope: RUN_TIME
        value: ${db.DATABASE_URL}

migrate deploy applies migrations already committed in prisma/migrations. It does not create them. The Designyff kits use npx prisma db push for local setup, and db push does not write migration files. Before the first deploy, create a baseline locally and commit it:

npx prisma migrate dev --name init
git add prisma/migrations
git commit -m "Add initial Prisma migration"

After that, every schema change is a migrate dev locally, a commit, and an automatic migrate deploy in the job. Do not run db push against production. The SaaS database schema article covers the same rule.

Step 4: Watch the connection limit

DigitalOcean’s connection pool docs state that PostgreSQL clusters provide 25 connections per 1 GiB of RAM, with 3 reserved for maintenance. On the smallest 1 GiB cluster, that is 22 usable connections shared by every app instance, the migration job, and any admin tool you open.

One Next.js instance with Prisma’s default pool is usually fine. If you scale to several instances, create a PgBouncer connection pool on the cluster and bind its URL with ${db.<pool name>.DATABASE_URL}. In transaction mode, follow Prisma’s PgBouncer notes, and keep running migrations against the direct database URL, not the pool.

Step 5: Stripe webhooks

An App Platform service is always running, so there is no sleeping service to wake before a Stripe webhook arrives. Point Stripe’s production webhook at https://your-domain/api/stripe/webhook and put that endpoint’s signing secret, not the stripe listen secret, in STRIPE_WEBHOOK_SECRET. The handler is in Stripe webhooks with Next.js, and the state it writes is in synchronizing Stripe subscription state.

Deploy checklist

  1. engines.node pinned, prisma generate && next build as the build script, next start as the start script.
  2. A managed PostgreSQL cluster attached for production (the dev database only for previews).
  3. DATABASE_URL set to ${db.DATABASE_URL}, or ${db.DATABASE_PRIVATE_URL} in the same VPC.
  4. prisma/migrations committed and a PRE_DEPLOY job running npx prisma migrate deploy. No migrations in the build.
  5. NEXT_PUBLIC_ variables scoped to build time, and secrets as RUN_TIME SECRET variables.
  6. A connection pool before you scale past one or two instances.
  7. A custom domain, and the Stripe webhook endpoint pointed at it.

Create an app on DigitalOcean App Platform

FAQ

Can I host Next.js on the App Platform free tier? No. The free tier covers apps that only contain static sites. A static export (output: "export") qualifies, but you lose server features such as route handlers, server actions, and the Stripe webhook. A full Next.js server needs a paid container.

Is App Platform cheaper than a Droplet? Not per GiB of RAM. You pay App Platform for builds, HTTPS, patching, and rollbacks you would otherwise do yourself. Compare current prices on DigitalOcean’s Droplet pricing with the tables above for your size.

Will the Designyff starter kits deploy unchanged? That was not verified by running them on App Platform for this article. The kits expect DATABASE_URL, a Prisma schema, and Stripe environment variables, which is the contract this guide uses. You still add the migration job, the variable scopes, and the production webhook secret yourself.

Do I have to use the affiliate links? No. digitalocean.com works without them. The links are how Designyff gets credited if you do use them.

Product updates for developers shipping with Designyff kits.

Guides: Next.js, Stripe, and SaaS starter kits Professional website design for small businesses

Purchased source may be used in personal, commercial, and client projects. Do not redistribute or resell the original source. Terms of Service Privacy Policy

Designyff © 2026 | Starter kits for developers