Deploy Next.js to a server you own.

Push to a branch and Serversinc builds your Next.js app on your server, waits for it to answer, then swaps it in. No per-request bill.

dash.serversinc.io/applications
An application detail page with its deployments, status and settings

Serversinc runs Next.js like any other container.

Your Dockerfile, your server, one price that doesn't move with traffic.

Builds on push

Connect the repository and branch. Every push builds your Dockerfile on the server and ships it.

Zero-downtime deploys

Rolling deploys wait for your health route to answer, and the old version keeps serving until it does.

HTTPS on your domain

The proxy on your server issues the certificate and routes the domain to your app.

Variables in one place

Paste your .env, mark secrets, and every deploy gets the same values.

Logs from the container

Read the Next.js server output under Logs, without an SSH session.

Traffic isn't metered

Builds and bandwidth aren't billed. A busy day costs what a quiet one does.

Deploy Next.js in four steps.

Tested with a fresh Next.js 16 app on Node.js 22. The same files work for an existing App Router or Pages Router app.

You’ll need a server connected to Serversinc and the Serversinc GitHub App installed on your repository (Settings → Integrations).

Add a Dockerfile

Turn on standalone output first. Next.js then copies only the files the server needs into .next/standalone, with a server.js to start it. The image stays small and doesn’t carry the build’s node_modules.

next.config.ts
import type { NextConfig } from 'next';
const nextConfig: NextConfig = {
output: 'standalone',
};
export default nextConfig;

Add a route for the health check. It answers without touching your pages or data, so a slow page doesn’t fail a deploy:

src/app/api/health/route.ts
export function GET() {
return Response.json({ status: 'ok' });
}

Serversinc builds the Dockerfile at the root of your repository. This one installs dependencies, builds the app, and copies only the standalone output into the final image.

Dockerfile
FROM node:22-alpine AS deps
WORKDIR /app
COPY package.json package-lock.json ./
RUN npm ci
FROM node:22-alpine AS build
WORKDIR /app
ENV NEXT_TELEMETRY_DISABLED=1
COPY --from=deps /app/node_modules ./node_modules
COPY . .
RUN npm run build
FROM node:22-alpine
WORKDIR /app
ENV NODE_ENV=production \
NEXT_TELEMETRY_DISABLED=1 \
PORT=3000 \
HOSTNAME=0.0.0.0
COPY --from=build --chown=node:node /app/.next/standalone ./
COPY --from=build --chown=node:node /app/.next/static ./.next/static
COPY --from=build --chown=node:node /app/public ./public
USER node
EXPOSE 3000
CMD ["node", "server.js"]

HOSTNAME=0.0.0.0 makes the server listen on every interface, so the proxy can reach it. Keep local files out of the build:

.dockerignore
.git
.next
node_modules
.env*
!.env.production
Dockerfile

Commit package-lock.json. If you use pnpm or Yarn, change the install line to pnpm install --frozen-lockfile or yarn install --immutable.

Create the application

  1. Open Applications, select New application, then GitHub app.
  2. Choose the server, the repository and the branch. Name it after your app, such as storefront.
  3. On Variables, select Paste .env and paste your production values. Mark API keys and passwords as secret. The server reads these at runtime.
  4. On Labels, add traefik.http.services.storefront.loadbalancer.server.port=3000. The health check and the proxy both use this port.
  5. On Settings, set Deploy strategy to Rolling and Health check to /api/health.
  6. Select Deploy.

NEXT_PUBLIC_ variables are different. Next.js writes them into the bundle during the build, so commit them in .env.production instead. They end up in the browser, so they must not hold secrets.

When the deployment shows Completed, open Logs. You’ll see Next.js report that it’s ready.

Put it on a domain

  1. Point an A record for shop.example.com at the server’s IP address.
  2. On the application’s Settings, enter shop.example.com under Domain and save. The Labels tab now shows a traefik.http.routers.storefront.rule label. The router takes its name from the application.
  3. On Labels, add these three:
Labels
traefik.http.routers.storefront.entrypoints=websecure
traefik.http.routers.storefront.tls=true
traefik.http.routers.storefront.tls.certresolver=le
  1. Deploy again. The certificate is issued once the domain resolves to the server.

Open https://shop.example.com. The container port isn’t published on the host, so outside traffic reaches the app only through the proxy.

Ship a change

Push to the branch. Serversinc builds the new image on the server and rolls it over once /api/health answers. If the new version never answers, Serversinc removes it and the old one keeps serving.

To deploy from CI instead, use the application’s deploy trigger. For the Dockerfile explained in more depth, read Next.js in Docker.

One flat price for the whole Next.js stack.

£5 a month covers your first three servers. Every server after that adds £2 a month. Builds and bandwidth are on the house, and the servers stay on your provider and your bill.

Next.js on Serversinc, answered.

Ship your Next.js app today.

Connect a server you already run, or provision one on your cloud account. £5 a month covers the first three.