Menu
Szybki wybór
Hosting Domeny VPS SSL Kalkulator Porównania FAQ
Aktywne kody
Wszystkie kody rabatowe

Next.js na własnym VPS — deployment bez Vercela

Opublikowano: 10 kwietnia 2026 · Kategoria: VPS

Vercel to natywna platforma dla Next.js i jest wygodna — ale kosztowna przy poważnym ruchu i zamknięta dla zaawansowanych konfiguracji. Własny VPS daje pełną kontrolę: możesz uruchomić kilka aplikacji na jednym serwerze, skonfigurować cache na poziomie Nginx, używać własnej bazy danych i płacić stałą kwotę niezależnie od ruchu. Ten artykuł pokazuje jak wdrożyć Next.js 14+ (App Router i Pages Router) na VPS z PM2, Nginx i opcjonalnie Dockerem.

Konfiguracja next.config.js dla produkcji

// next.config.js / next.config.ts
/** @type {import('next').NextConfig} */
const nextConfig = {
  output: 'standalone',  // KLUCZOWE — generuje samodzielny katalog do deployu

  // Optymalizacja obrazow (WAZNE: nie dziala bez Node.js po stronie serwera)
  images: {
    domains: ['cdn.example.com'],
    formats: ['image/avif', 'image/webp'],
  },

  // Naglowki bezpieczenstwa (alternatywnie w Nginx)
  async headers() {
    return [
      {
        source: '/(.*)',
        headers: [
          { key: 'X-Content-Type-Options', value: 'nosniff' },
          { key: 'X-Frame-Options', value: 'DENY' },
          { key: 'Referrer-Policy', value: 'strict-origin-when-cross-origin' },
        ],
      },
    ];
  },

  // Przekierowania
  async redirects() {
    return [
      { source: '/old-page', destination: '/new-page', permanent: true },
    ];
  },
};

export default nextConfig;

Build produkcyjny i struktura standalone

# Na serwerze VPS
# 1. Zainstaluj Node.js (LTS przez nvm)
curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.7/install.sh | bash
source ~/.bashrc
nvm install --lts
node --version   # v20.x lub v22.x

# 2. Sklonuj repo i zbuduj
git clone https://github.com/twoj-user/twoj-projekt.git /srv/nextjs
cd /srv/nextjs
npm ci              # instalacja zalenosci (z package-lock.json)
npm run build       # generuje .next/standalone

# Struktura po buildzie z output: 'standalone':
# .next/
# ├── standalone/
# │   ├── server.js       <--- PLIK STARTOWY
# │   ├── node_modules/   <--- minimalne zależności
# │   └── .next/
# ├── static/             <--- pliki statyczne (serwowane przez Nginx)
# └── cache/

# 3. Skopiuj pliki statyczne do standalone (wymagane!)
cp -r public .next/standalone/public
cp -r .next/static .next/standalone/.next/static

# 4. Test uruchomienia
node .next/standalone/server.js
# Domyslnie sluchuje na porcie 3000
# HOSTNAME i PORT kontrolowane przez zmienne srodowiskowe

PM2 — process manager dla Next.js

# Instalacja PM2 globalnie
npm install -g pm2

# ecosystem.config.cjs (dla ESM-compat)
module.exports = {
  apps: [
    {
      name: 'nextjs-app',
      script: '.next/standalone/server.js',
      cwd: '/srv/nextjs',
      instances: 2,           // lub 'max' dla wszystkich rdzeni
      exec_mode: 'cluster',   // UWAGA: ISR cache nie jest wspoldzielony miedzy instanceami
      autorestart: true,
      max_memory_restart: '1G',
      env_production: {
        NODE_ENV: 'production',
        PORT: 3000,
        HOSTNAME: '127.0.0.1',
        // Nie wpisuj sekretow tutaj — uzyj .env.production lub EnvironmentFile
      },
      error_file: '/var/log/nextjs/error.log',
      out_file: '/var/log/nextjs/out.log',
    },
  ],
};

# Start i autostart
sudo mkdir -p /var/log/nextjs
pm2 start ecosystem.config.cjs --env production
pm2 save && pm2 startup

# Aktualizacja aplikacji (zero-downtime)
cd /srv/nextjs && git pull && npm ci && npm run build
cp -r public .next/standalone/public
cp -r .next/static .next/standalone/.next/static
pm2 reload nextjs-app

Nginx z cache dla plików statycznych

Kluczowa różnica w stosunku do Vercela: musisz sam skonfigurować cache dla statycznych assetów. Next.js generuje pliki w _next/static/ z hashem w nazwie — można je cache'ować na rok. Nginx obsłuży je bezpośrednio z dysku, bez angażowania Node.js.

# /etc/nginx/sites-available/nextjs-app
server {
    listen 443 ssl http2;
    server_name example.com www.example.com;

    ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem;
    ssl_protocols TLSv1.2 TLSv1.3;

    # Pliki statyczne serwowane bezposrednio — omijamy Node.js
    location /_next/static/ {
        alias /srv/nextjs/.next/static/;
        expires 1y;
        add_header Cache-Control "public, immutable";
        add_header Vary Accept-Encoding;
        gzip_static on;
    }

    # Pliki z katalogu public/
    location /public/ {
        alias /srv/nextjs/public/;
        expires 30d;
        add_header Cache-Control "public";
    }

    # Favicon i robots.txt
    location = /favicon.ico {
        root /srv/nextjs/public;
        expires 30d;
    }

    # Next.js Node.js server
    location / {
        proxy_pass http://127.0.0.1:3000;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection 'upgrade';
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
        proxy_cache_bypass $http_upgrade;
    }
}

Zmienne środowiskowe i sekrety

# /srv/nextjs/.env.production.local (NIE commituj do git)
DATABASE_URL=postgresql://user:pass@localhost:5432/mydb
NEXTAUTH_SECRET=twoj-super-tajny-klucz
NEXTAUTH_URL=https://example.com
NEXT_PUBLIC_API_URL=https://api.example.com  # ta zostanie wbudowana w JS (publiczna!)

# Uwaga: NEXT_PUBLIC_* sa wbudowane w JavaScript podczas budowania
# — NIE mozna ich zmienic bez rebuildu aplikacji
# Wszystkie inne zmienne sa dostepne tylko po stronie serwera

# Zaladowanie .env w PM2 (dodaj do ecosystem.config.cjs):
# env_production: {
#   NODE_ENV: 'production',
#   PORT: 3000,
# }
# Lub uzyj "node-config" / dotenv w server.js

# Alternatywnie — systemd z EnvironmentFile:
# /etc/systemd/system/nextjs.service
# ...
# EnvironmentFile=/srv/nextjs/.env.production.local
# ExecStart=/usr/bin/node /srv/nextjs/.next/standalone/server.js

Docker multi-stage build (alternatywa)

# Dockerfile dla Next.js standalone
FROM node:20-alpine AS deps
WORKDIR /app
COPY package.json package-lock.json ./
RUN npm ci --only=production

FROM node:20-alpine AS builder
WORKDIR /app
COPY --from=deps /app/node_modules ./node_modules
COPY . .
ENV NEXT_TELEMETRY_DISABLED=1
RUN npm run build

FROM node:20-alpine AS runner
WORKDIR /app
ENV NODE_ENV=production
ENV NEXT_TELEMETRY_DISABLED=1

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

COPY --from=builder /app/.next/standalone ./
COPY --from=builder /app/.next/static ./.next/static
COPY --from=builder /app/public ./public

USER nextjs
EXPOSE 3000
ENV PORT=3000 HOSTNAME="0.0.0.0"

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

# docker-compose.yml (uproszczony)
# services:
#   nextjs:
#     build: .
#     restart: unless-stopped
#     environment:
#       - DATABASE_URL=${DATABASE_URL}
#     ports:
#       - "127.0.0.1:3000:3000"

Vercel vs VPS — porównanie kosztów

Aspekt Vercel Free Vercel Pro VPS Contabo (4 vCPU)
Cena miesięczna 0 USD $20 + użycie ~25 EUR (stała)
Bandwidth 100 GB/msc 1 TB/msc Zwykle nielimitowany
Liczba projektów Unlimited Unlimited Unlimited (1 serwer)
Własna baza danych Vercel Postgres ($) Vercel Postgres ($) PostgreSQL na serwerze
Edge Functions Tak (globalnie) Tak (globalnie) Nie (jeden region)
Konfiguracja Zero Zero Wymagana (Nginx, PM2)

Najczęstsze pytania

Ile kosztuje hosting Next.js na VPS vs Vercel? +
Vercel Pro kosztuje $20/msc per użytkownik + $40/msc za dodatkowe "Compute Units" przy większym ruchu. Dla małych projektów Vercel Free jest wystarczający, ale ma limity (100 GB bandwidth, 1000 deployments). VPS Contabo z 4 vCPU i 8 GB RAM kosztuje ok. 20-25 EUR/msc i może obsłużyć wiele aplikacji Next.js jednocześnie. Break-even: jeśli używasz Next.js do poważnego projektu z ruchem, VPS opłaca się już przy 1-2 aplikacjach.
Co to jest Next.js standalone build i kiedy go używać? +
Standalone build (output: "standalone" w next.config.js) generuje samodzielny katalog .next/standalone z minimalnym node_modules potrzebnym do uruchomienia. Nie wymaga instalacji zależności na serwerze — idealny do Dockera i deploymentu. Plik startowy: node .next/standalone/server.js. Statyczne pliki z public/ i .next/static/ serwujesz przez Nginx (nie przez Node.js — byłoby wolniejsze).
Jak działa ISR (Incremental Static Regeneration) na własnym serwerze? +
ISR działa na self-hosted Next.js — strony regenerują się w tle po revalidate sekundach. Nie potrzebujesz Vercela. Pamiętaj: ISR wymaga persystentnego cache na dysku — kontenery Docker restartujące się tracą cache. Jeśli używasz wielu instancji PM2 (cluster mode), każda ma osobny cache na dysku — strony mogą się różnić między workerami. Rozwiązanie: Redis cache handler (@neshca/cache-handler).
Czy Next.js App Router działa inaczej niż Pages Router na VPS? +
Na poziomie deploymentu oba routery działają tak samo na VPS — obydwa wymagają serwera Node.js (PM2) i Nginx przed nim. App Router używa React Server Components, co oznacza więcej pracy po stronie serwera. Przy dużym ruchu App Router z wieloma Server Components może być bardziej zasobochłonny niż Pages Router z getServerSideProps. Monitoruj zużycie CPU i RAM po migracji.

Sprawdź oferty pasujące do tego scenariusza

Poniżej masz szybkie przejścia do ofert i stron z kodami rabatowymi tam, gdzie są dostępne.