PreviewDrop for Next.js

Self-hosted deploy previews for Next.js

Push a branch, get a live preview URL. PreviewDrop builds your Next.js app in standalone mode, runs it as a real Node process, and posts the link to the pull request in under 60 seconds — on your own infra, password-protected, flat-priced.

TL;DR
Set output: 'standalone' in next.config, add the Dockerfile, push. PreviewDrop builds and runs server.js behind a TLS-terminated subdomain. Full Node runtime — middleware, route handlers, ISR and server actions all work, and previews are password-protected by default.

Dockerfile

Drop this at the root of your repo. PreviewDrop picks it up on the next push and builds it into a container behind a TLS-terminated subdomain.

Dockerfile
FROM node:22-slim AS build WORKDIR /app COPY package*.json ./ RUN npm ci COPY . . RUN npm run build FROM node:22-slim WORKDIR /app ENV NODE_ENV=production HOSTNAME=0.0.0.0 # Requires output: 'standalone' in next.config.{js,ts} COPY --from=build /app/.next/standalone ./ COPY --from=build /app/.next/static ./.next/static COPY --from=build /app/public ./public EXPOSE 3000 CMD ["node", "server.js"]

Environment variables

Set these in the Variables tab of your PreviewDrop project. They're encrypted at rest and injected into every preview container at start.

VariableExample valueNote
PORT3000PreviewDrop injects this; the standalone server.js reads it automatically.
DATABASE_URLpostgres://user:pass@host:5432/dbServer-side only env is read at runtime — safe to set here.
NEXT_PUBLIC_API_URLhttps://api.example.comNEXT_PUBLIC_* is inlined at BUILD time — see the gotcha below.

Common gotchas

Set output: 'standalone' in next.config

The slim runtime image copies only .next/standalone, which Next.js produces only when output: 'standalone' is set. Without it there’s no server.js to run and the container exits immediately.

NEXT_PUBLIC_* vars are baked at build time

Anything prefixed NEXT_PUBLIC_ is inlined into the client bundle during npm run build, not read at container start. Set those project variables before the build runs (they’re available as build args), or keep client-side config in non-secret runtime fetches. Server-only secrets are read at runtime and are fine to set normally.

Copy static and public into the standalone output

The standalone server.js does not include .next/static or public. Both must be copied next to it (as in the Dockerfile) or your CSS, JS chunks and images 404.

Bind to 0.0.0.0

Set HOSTNAME=0.0.0.0 (done in the Dockerfile) so the standalone server listens on all interfaces. The default can bind to localhost inside the container, which the proxy can’t reach.

Why not Vercel or Netlify?

Vercel is an excellent home for Next.js — PreviewDrop isn’t trying to replace it for everyone. It’s for teams who self-host Next.js (in Docker, on their own cloud, or next to a backend API), want password-protected previews to share with clients, prefer flat per-workspace pricing over per-seat, or run Next.js alongside a Django/Rails/Go service that needs previews too. One tool, one Dockerfile, every branch — frontend and backend.

Preview your Next.js app in 5 minutes

Connect a repo, push a branch, get a URL. No credit card, no trial clock.

Start free