DU
Digital Universe
Back to Blog
Tutorial2025-01-208 min read

How to Deploy Next.js on a Hetzner VPS

Deploy your Next.js application on a Hetzner VPS using Coolify or Docker. Covers build configuration, environment variables, and production optimization.

Deploying Next.js Beyond Vercel

Next.js is often associated with Vercel, but it's just a Node.js application — it runs anywhere Node runs. Here's how to deploy it on your Hetzner VPS.

Method 1: Coolify (Recommended)

If you've set up Coolify on your VPS, deploying Next.js is straightforward:

1. Connect your repo in Coolify's dashboard

2. Select "Nixpacks" or "Dockerfile" as the build method

3. Set environment variables in the Coolify UI

4. Add your domain — Coolify handles SSL automatically

5. Deploy

Coolify auto-detects Next.js and configures the build correctly.

Method 2: Docker

Create a Dockerfile in your project root:

FROM node:20-alpine AS base

FROM base AS deps
WORKDIR /app
COPY package.json package-lock.json ./
RUN npm ci

FROM base AS builder
WORKDIR /app
COPY --from=deps /app/node_modules ./node_modules
COPY . .
RUN npm run build

FROM base AS runner
WORKDIR /app
ENV NODE_ENV production

RUN addgroup --system --gid 1001 nodejs
RUN adduser --system --uid 1001 nextjs

COPY --from=builder /app/public ./public
COPY --from=builder --chown=nextjs:nodejs /app/.next/standalone ./
COPY --from=builder --chown=nextjs:nodejs /app/.next/static ./.next/static

USER nextjs
EXPOSE 3000
ENV PORT 3000

CMD ["node", "server.js"]

Requires output: 'standalone' in your next.config.js:

/** @type {import('next').NextConfig} */
const nextConfig = {
  output: 'standalone',
}
module.exports = nextConfig

Build and run:

docker build -t my-nextjs-app .
docker run -d -p 3000:3000 --name my-app my-nextjs-app

Method 3: Docker Compose

For apps with a database:

version: "3.8"
services:
  app:
    build: .
    ports:
      - "3000:3000"
    environment:
      - DATABASE_URL=postgres://user:pass@db:5432/myapp
      - NEXTAUTH_SECRET=your-secret
      - NEXTAUTH_URL=https://yourdomain.com
    depends_on:
      - db
    restart: unless-stopped

  db:
    image: postgres:16-alpine
    volumes:
      - pgdata:/var/lib/postgresql/data
    environment:
      - POSTGRES_USER=user
      - POSTGRES_PASSWORD=pass
      - POSTGRES_DB=myapp
    restart: unless-stopped

volumes:
  pgdata:

Production Considerations

Environment Variables: Never bake secrets into your Docker image. Use environment variables at runtime.

Health Checks: Add a health check endpoint:

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

Reverse Proxy: Use Coolify's Traefik or set up Nginx/Caddy for:

  • SSL termination
  • HTTP → HTTPS redirect
  • Gzip compression
  • Static asset caching

Memory: A Next.js standalone server typically uses 100-200MB RAM. On a CPX42 with 16GB, you can run many instances.

Performance Tips

1. Enable standalone output — reduces deployed size by 80%+

2. Use sharp for image optimizationnpm install sharp

3. Set proper cache headers for static assets

4. Use ISR/SSG where possible to reduce server load

5. Monitor with Netdata or similar

Our complete guide covers deploying Next.js as part of a full production stack, including database setup, SSL, monitoring, and CI/CD workflows.

#nextjs#hetzner#deployment#coolify#docker

Want the Complete Setup Guide?

This blog post covers the basics. Our premium guide includes step-by-step commands, exact configurations, and the solutions to every gotcha we encountered.