💡 Hinweis: Dieses Tutorial setzt voraus, dass du einen normalen Benutzer mit sudo-Rechten verwendest — wie im Tutorial Debian 13 Server absichern beschrieben.
Einleitung — Was ist Next.js und warum Self-Hosting?
Next.js ist das beliebteste React-Framework für produktionsreife Webanwendungen. Es bietet Server-Side Rendering (SSR), Static Site Generation (SSG), API-Routes und vieles mehr — alles out of the box.
Aber warum solltet ihr eure Next.js App selbst hosten, statt Vercel oder Netlify zu nutzen?
- Volle Kontrolle — Keine Vendor-Lock-in, keine überraschenden Kosten
- Datenschutz — Eure Daten bleiben auf eurem Server (DSGVO!)
- Performance — Eigener Server in der Nähe eurer Nutzer
- Flexibilität — Beliebige Server-Konfiguration, Datenbanken, Cron-Jobs
- Kosten — Ein 5€/Monat VPS reicht für viele Projekte
In diesem Guide deployen wir eine Next.js App auf Debian 13 (Trixie) — Schritt für Schritt, von der Node.js Installation bis zu Zero-Downtime Deployments.
Voraussetzungen
Bevor wir loslegen, solltet ihr folgendes haben:
- Einen Debian 13 Server mit Root-Zugang (VPS oder Dedicated)
- Nginx installiert und konfiguriert — siehe Tutorial #2: Nginx auf Debian 13 installieren
- SSL mit Let’s Encrypt eingerichtet — siehe Tutorial #3: SSL-Zertifikate mit Certbot
- Grundkenntnisse in systemd — siehe Tutorial #7: systemd Services verstehen
- Eine Domain, die auf euren Server zeigt
- Ein Next.js Projekt, das lokal funktioniert
💡 Tipp: Falls ihr noch kein Next.js Projekt habt, könnt ihr mit npx create-next-app@latest meine-app schnell eins erstellen.
1. Node.js installieren
Next.js braucht Node.js. Die Version aus den Debian-Repos ist oft veraltet, deshalb nutzen wir das NodeSource Repository für eine aktuelle LTS-Version.
NodeSource Repository hinzufügen
# System aktualisieren
sudo apt update && sudo apt upgrade -y
# Benötigte Pakete installieren
sudo apt install -y curl gnupg2 ca-certificates
# NodeSource Setup-Script für Node.js 22.x (LTS) herunterladen und ausführen
curl -fsSL https://deb.nodesource.com/setup_22.x | sudo -E bash -
# Node.js installieren
sudo apt install -y nodejsInstallation prüfen
node --version
# v22.x.x
npm --version
# 10.x.x⚠️ Wichtig: Next.js 15 benötigt mindestens Node.js 18.18. Wir empfehlen die aktuelle LTS-Version (22.x). Ältere Projekte auf Next.js 13/14 laufen auch mit Node 18.x oder 20.x.
Optional: Corepack für pnpm/yarn aktivieren
Falls euer Projekt pnpm oder yarn nutzt:
# Corepack aktivieren (in Node.js enthalten)
sudo corepack enable
# pnpm oder yarn stehen jetzt zur Verfügung
pnpm --version
yarn --version2. Next.js Projekt für Production vorbereiten
Bevor wir das Projekt auf den Server bringen, bereiten wir es lokal vor.
next.config.js für Production
Erstellt oder passt eure next.config.js (oder next.config.mjs) an:
/** @type {import('next').NextConfig} */
const nextConfig = {
// Standalone-Output: Erzeugt einen eigenständigen Server
// Ideal für Self-Hosting — enthält alle Dependencies
output: 'standalone',
// Bilder von externen Domains erlauben
images: {
remotePatterns: [
{
protocol: 'https',
hostname: 'beispiel.de',
},
],
},
// Environment Variables, die im Browser verfügbar sein sollen
env: {
NEXT_PUBLIC_API_URL: process.env.NEXT_PUBLIC_API_URL,
},
// PoweredBy-Header entfernen (Security)
poweredByHeader: false,
// Strict Mode für bessere Entwicklung
reactStrictMode: true,
};
module.exports = nextConfig;✅ Warum output: 'standalone'?
Der Standalone-Modus erzeugt einen minimalen Server mit allen benötigten Dependencies. Statt das gesamte node_modules zu deployen (oft 500MB+), bekommt ihr einen schlanken Build (~50-100MB). Perfekt für Server-Deployments.
.env Dateien verstehen
Next.js nutzt verschiedene .env Dateien:
| Datei | Zweck | Im Git? |
|---|---|---|
.env | Standardwerte für alle Umgebungen | Ja |
.env.local | Lokale Overrides (Secrets!) | Nein |
.env.production | Production-spezifisch | Ja (keine Secrets) |
.env.production.local | Production Secrets | Nein |
Beispiel .env.production:
# Öffentlich (im Browser sichtbar) — Prefix NEXT_PUBLIC_
NEXT_PUBLIC_API_URL=https://api.meinedomain.de
NEXT_PUBLIC_SITE_URL=https://meinedomain.de
# Nur serverseitig (NIE im Browser)
DATABASE_URL=postgresql://user:password@localhost:5432/mydb
JWT_SECRET=super-geheimes-token-hier
SMTP_HOST=mail.meinedomain.de🔒 Sicherheit: Variablen mit NEXT_PUBLIC_ Prefix landen im JavaScript-Bundle und sind für jeden sichtbar! Packt niemals Secrets (API-Keys, Passwörter) in NEXT_PUBLIC_ Variablen.
3. Projekt auf den Server bringen
Es gibt mehrere Wege, euren Code auf den Server zu bekommen:
Option A: Git Clone (empfohlen)
# Auf dem Server:
cd /var/www
sudo git clone https://github.com/euer-user/euer-projekt.git meine-app
sudo chown -R www-data:www-data meine-app
cd meine-appFür private Repos mit SSH-Key:
# SSH-Key auf dem Server generieren
ssh-keygen -t ed25519 -C "server@meinedomain.de"
# Public Key bei GitHub/GitLab hinterlegen
cat ~/.ssh/id_ed25519.pub
# Dann per SSH clonen
sudo git clone git@github.com:euer-user/euer-projekt.git meine-appOption B: rsync (schnell bei Updates)
# Von eurem lokalen Rechner:
rsync -avz --exclude='node_modules' --exclude='.next' --exclude='.git' \
./mein-projekt/ root@mein-server:/var/www/meine-app/Option C: SCP (einfach)
# Projekt als Archiv packen und übertragen
tar czf meine-app.tar.gz --exclude='node_modules' --exclude='.next' mein-projekt/
scp meine-app.tar.gz root@mein-server:/var/www/
# Auf dem Server entpacken
ssh root@mein-server
cd /var/www
tar xzf meine-app.tar.gz
mv mein-projekt meine-app💡 Empfehlung: Nutzt Git für das Deployment. So habt ihr Versionierung, könnt einfach zurückrollen und Updates mit git pull einspielen.
4. Build auf dem Server
Jetzt installieren wir die Dependencies und bauen das Projekt:
cd /var/www/meine-app
# Dependencies installieren (nur Production-Dependencies)
npm ci --omit=dev
# Falls ihr devDependencies für den Build braucht:
npm ci
# Projekt bauen
npm run buildWas passiert beim Build?
Der npm run build Befehl erzeugt:
.next/— Kompilierte Seiten, Assets, Server-Bundle.next/standalone/— Eigenständiger Server (beioutput: 'standalone').next/static/— Statische Assets (JS, CSS, Bilder)
Build-Ausgabe prüfen
# Prüfen ob der Build erfolgreich war
ls -la .next/
ls -la .next/standalone/ # Falls standalone aktiviert
# Standalone-Server testen
node .next/standalone/server.js
# Sollte auf Port 3000 starten⚠️ Standalone-Modus: Bei output: 'standalone' müsst ihr das public/ Verzeichnis und .next/static/ manuell in den Standalone-Ordner kopieren:
cp -r public .next/standalone/public
cp -r .next/static .next/standalone/.next/static5. Next.js als systemd Service einrichten
Damit Next.js automatisch startet und nach Crashes neu gestartet wird, richten wir einen systemd Service ein.
Service-Datei erstellen
sudo nano /etc/systemd/system/nextjs-meine-app.serviceInhalt für den normalen Modus (ohne standalone):
[Unit]
Description=Next.js - Meine App
Documentation=https://nextjs.org
After=network.target
[Service]
Type=simple
User=www-data
Group=www-data
WorkingDirectory=/var/www/meine-app
ExecStart=/usr/bin/node node_modules/.bin/next start -p 3000
Restart=on-failure
RestartSec=10
# Umgebungsvariablen
Environment=NODE_ENV=production
Environment=PORT=3000
# Sicherheit
NoNewPrivileges=true
ProtectSystem=strict
ReadWritePaths=/var/www/meine-app
# Ressourcen-Limits
LimitNOFILE=65536
[Install]
WantedBy=multi-user.targetInhalt für den Standalone-Modus:
[Unit]
Description=Next.js Standalone - Meine App
Documentation=https://nextjs.org
After=network.target
[Service]
Type=simple
User=www-data
Group=www-data
WorkingDirectory=/var/www/meine-app/.next/standalone
ExecStart=/usr/bin/node server.js
Restart=on-failure
RestartSec=10
Environment=NODE_ENV=production
Environment=PORT=3000
Environment=HOSTNAME=0.0.0.0
# EnvironmentFile für Secrets (empfohlen!)
EnvironmentFile=/var/www/meine-app/.env.production.local
NoNewPrivileges=true
ProtectSystem=strict
ReadWritePaths=/var/www/meine-app
LimitNOFILE=65536
[Install]
WantedBy=multi-user.targetService aktivieren und starten
# systemd neu laden
sudo systemctl daemon-reload
# Service aktivieren (Autostart)
sudo systemctl enable nextjs-meine-app
# Service starten
sudo systemctl start nextjs-meine-app
# Status prüfen
sudo systemctl status nextjs-meine-appDie Ausgabe sollte so aussehen:
● nextjs-meine-app.service - Next.js - Meine App
Loaded: loaded (/etc/systemd/system/nextjs-meine-app.service; enabled)
Active: active (running) since ...
Main PID: 12345 (node)
CGroup: /system.slice/nextjs-meine-app.service
└─12345 /usr/bin/node server.jsNützliche systemd-Befehle
# Logs anzeigen
sudo journalctl -u nextjs-meine-app -f
# Service neustarten
sudo systemctl restart nextjs-meine-app
# Service stoppen
sudo systemctl stop nextjs-meine-app6. Nginx als Reverse Proxy konfigurieren
Nginx leitet Anfragen an den Next.js Server weiter und übernimmt SSL-Terminierung, Caching und Compression.
Nginx Server Block erstellen
sudo nano /etc/nginx/sites-available/meine-appserver {
listen 80;
listen [::]:80;
server_name meinedomain.de www.meinedomain.de;
# Redirect zu HTTPS
return 301 https://$host$request_uri;
}
server {
listen 443 ssl http2;
listen [::]:443 ssl http2;
server_name meinedomain.de www.meinedomain.de;
# SSL-Zertifikate (Let's Encrypt)
ssl_certificate /etc/letsencrypt/live/meinedomain.de/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/meinedomain.de/privkey.pem;
include /etc/letsencrypt/options-ssl-nginx.conf;
ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem;
# Sicherheits-Header
add_header X-Frame-Options "SAMEORIGIN" always;
add_header X-Content-Type-Options "nosniff" always;
add_header X-XSS-Protection "1; mode=block" always;
add_header Referrer-Policy "strict-origin-when-cross-origin" always;
# Statische Dateien direkt von Nginx servieren
location /_next/static/ {
alias /var/www/meine-app/.next/static/;
expires 365d;
add_header Cache-Control "public, immutable";
access_log off;
}
# Public-Ordner (Favicon, robots.txt, etc.)
location /public/ {
alias /var/www/meine-app/public/;
expires 30d;
access_log off;
}
# Favicon direkt
location = /favicon.ico {
alias /var/www/meine-app/public/favicon.ico;
access_log off;
}
# Alles andere an Next.js weiterleiten
location / {
proxy_pass http://127.0.0.1:3000;
proxy_http_version 1.1;
# WebSocket-Support (für HMR in Dev, optional in Production)
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection 'upgrade';
# Wichtige Header weiterleiten
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;
# Timeouts
proxy_connect_timeout 60s;
proxy_send_timeout 60s;
proxy_read_timeout 60s;
# Cache deaktivieren für dynamische Inhalte
proxy_cache_bypass $http_upgrade;
}
# Gzip-Kompression
gzip on;
gzip_vary on;
gzip_proxied any;
gzip_comp_level 6;
gzip_types text/plain text/css application/json application/javascript
text/xml application/xml application/xml+rss text/javascript
image/svg+xml;
}Konfiguration aktivieren
# Symlink erstellen
sudo ln -s /etc/nginx/sites-available/meine-app /etc/nginx/sites-enabled/
# Konfiguration testen
sudo nginx -t
# Nginx neu laden
sudo systemctl reload nginxTesten
# Lokal testen (auf dem Server)
curl -I http://127.0.0.1:3000
# Sollte 200 OK zurückgeben
# Von außen testen
curl -I https://meinedomain.de
# Sollte 200 OK mit SSL zurückgeben7. SSL mit Let’s Encrypt hinzufügen
Falls ihr noch kein SSL-Zertifikat habt (was ihr aus Tutorial #3 bereits haben solltet):
# Certbot installieren
sudo apt install -y certbot python3-certbot-nginx
# Zertifikat anfordern
sudo certbot --nginx -d meinedomain.de -d www.meinedomain.de
# Auto-Renewal testen
sudo certbot renew --dry-runCertbot modifiziert automatisch eure Nginx-Konfiguration und fügt die SSL-Einstellungen hinzu.
8. Umgebungsvariablen sicher verwalten
Secrets gehören nicht in Git-Repos. Hier sind sichere Alternativen:
Option A: systemd EnvironmentFile (empfohlen)
Erstellt eine Datei mit euren Secrets:
sudo nano /var/www/meine-app/.env.production.localDATABASE_URL=postgresql://user:password@localhost:5432/mydb
JWT_SECRET=euer-super-geheimes-token
SMTP_PASSWORD=mail-passwort
NEXT_PUBLIC_API_URL=https://api.meinedomain.deBerechtigungen setzen:
# Nur root und www-data dürfen lesen
sudo chown root:www-data /var/www/meine-app/.env.production.local
sudo chmod 640 /var/www/meine-app/.env.production.localIn der systemd Service-Datei referenzieren:
# In /etc/systemd/system/nextjs-meine-app.service
[Service]
EnvironmentFile=/var/www/meine-app/.env.production.localOption B: Direkt in systemd (für wenige Variablen)
[Service]
Environment=NODE_ENV=production
Environment=PORT=3000
Environment=DATABASE_URL=postgresql://user:password@localhost:5432/mydb🔒 Wichtig: Variablen direkt in der Service-Datei sind mit sudo systemctl show für alle Nutzer sichtbar! Nutzt EnvironmentFile für sensible Daten.
Option C: .env Datei im Projekt
Next.js liest .env.production.local automatisch beim Start. Stellt sicher, dass die Datei in .gitignore steht:
echo ".env*.local" >> .gitignore💡 Build-Time vs. Runtime: Variablen mit NEXT_PUBLIC_ werden zur Build-Zeit eingebettet und können danach nicht mehr geändert werden. Server-seitige Variablen werden zur Laufzeit gelesen. Plant entsprechend!
9. Zero-Downtime Deployments
Bei einem normalen Deployment gibt es eine kurze Downtime während des Restarts. Hier eine einfache Strategie für Zero-Downtime:
Einfache Strategie: Zwei Instanzen
Das Prinzip: Eine neue Instanz starten, testen, dann die alte ersetzen.
#!/bin/bash
# deploy.sh — Einfaches Zero-Downtime Deployment
set -e
APP_DIR="/var/www/meine-app"
SERVICE="nextjs-meine-app"
echo "🚀 Deployment gestartet..."
cd "$APP_DIR"
# 1. Code aktualisieren
echo "📥 Code pullen..."
git pull origin main
# 2. Dependencies installieren
echo "📦 Dependencies installieren..."
npm ci
# 3. Neuen Build erstellen
echo "🔨 Build erstellen..."
npm run build
# 4. Standalone-Assets kopieren (falls standalone)
if [ -d ".next/standalone" ]; then
cp -r public .next/standalone/public 2>/dev/null || true
cp -r .next/static .next/standalone/.next/static
fi
# 5. Service neustarten
echo "🔄 Service neustarten..."
sudo systemctl restart "$SERVICE"
# 6. Warten und testen
sleep 3
if curl -s -o /dev/null -w "%{http_code}" http://127.0.0.1:3000 | grep -q "200"; then
echo "✅ Deployment erfolgreich!"
else
echo "❌ Deployment fehlgeschlagen! Logs prüfen:"
sudo journalctl -u "$SERVICE" --no-pager -n 20
exit 1
fi# Script ausführbar machen
chmod +x deploy.sh
# Deployment ausführen
./deploy.shFortgeschritten: Blue-Green mit zwei Ports
Für echte Zero-Downtime könnt ihr zwei Instanzen parallel laufen lassen:
#!/bin/bash
# blue-green-deploy.sh
BLUE_PORT=3000
GREEN_PORT=3001
NGINX_CONF="/etc/nginx/sites-available/meine-app"
APP_DIR="/var/www/meine-app"
# Aktuellen Port ermitteln
CURRENT_PORT=$(grep proxy_pass "$NGINX_CONF" | grep -oP '\d+' | tail -1)
if [ "$CURRENT_PORT" = "$BLUE_PORT" ]; then
NEW_PORT=$GREEN_PORT
else
NEW_PORT=$BLUE_PORT
fi
echo "Aktuell: Port $CURRENT_PORT → Neu: Port $NEW_PORT"
# Build durchführen
cd "$APP_DIR"
git pull origin main
npm ci && npm run build
# Neue Instanz starten
PORT=$NEW_PORT node .next/standalone/server.js &
NEW_PID=$!
sleep 5
# Testen
if curl -s -o /dev/null -w "%{http_code}" "http://127.0.0.1:$NEW_PORT" | grep -q "200"; then
# Nginx umschalten
sudo sed -i "s/proxy_pass http:\/\/127.0.0.1:$CURRENT_PORT/proxy_pass http:\/\/127.0.0.1:$NEW_PORT/" "$NGINX_CONF"
sudo nginx -t && sudo systemctl reload nginx
# Alte Instanz stoppen (nach Drain)
sleep 10
sudo systemctl stop "nextjs-meine-app"
echo "✅ Switch zu Port $NEW_PORT erfolgreich!"
else
kill $NEW_PID
echo "❌ Neue Instanz fehlerhaft, Rollback."
exit 1
fi10. PM2 als Alternative zu systemd
PM2 ist ein Process Manager speziell für Node.js. Hier ein Vergleich:
| Feature | systemd | PM2 |
|---|---|---|
| Bereits installiert | ✅ Ja | ❌ Nein |
| Auto-Restart | ✅ Ja | ✅ Ja |
| Log-Management | journalctl | pm2 logs (+ Rotation) |
| Cluster-Modus | ❌ Nein | ✅ Ja (Multi-Core) |
| Zero-Downtime Reload | Manuell | ✅ Eingebaut |
| Monitoring Dashboard | ❌ Nein | ✅ Ja (pm2 monit) |
| Memory Limit | cgroups | max_memory_restart |
| Systemintegration | ✅ Nativ | Via pm2 startup |
PM2 einrichten
# PM2 global installieren
sudo npm install -g pm2
# App starten
cd /var/www/meine-app
pm2 start npm --name "meine-app" -- start
# Oder mit Standalone:
pm2 start .next/standalone/server.js --name "meine-app"
# Cluster-Modus (nutzt alle CPU-Kerne):
pm2 start .next/standalone/server.js --name "meine-app" -i maxPM2 ecosystem.config.js
module.exports = {
apps: [{
name: 'meine-app',
script: '.next/standalone/server.js',
instances: 'max', // Alle CPU-Kerne nutzen
exec_mode: 'cluster', // Cluster-Modus
env: {
NODE_ENV: 'production',
PORT: 3000,
},
max_memory_restart: '500M', // Restart bei 500MB RAM
error_file: '/var/log/pm2/meine-app-error.log',
out_file: '/var/log/pm2/meine-app-out.log',
}],
};# Mit Config starten
pm2 start ecosystem.config.js
# Zero-Downtime Reload
pm2 reload meine-app
# Autostart einrichten
pm2 startup systemd
pm2 save💡 Empfehlung: Für einfache Setups reicht systemd völlig aus. Nutzt PM2, wenn ihr Cluster-Modus, eingebautes Zero-Downtime Reload oder das Monitoring-Dashboard braucht.
11. Static Export vs. Server-Side Rendering
Next.js kann eure App auf zwei grundlegend verschiedene Arten ausliefern:
Static Export (SSG)
Generiert reine HTML/CSS/JS-Dateien. Kein Node.js Server nötig.
// next.config.js
const nextConfig = {
output: 'export', // Statischer Export
};npm run build
# Erzeugt: out/ Ordner mit statischen DateienNginx-Konfiguration für Static Export:
server {
listen 443 ssl http2;
server_name meinedomain.de;
root /var/www/meine-app/out;
index index.html;
location / {
try_files $uri $uri.html $uri/ /404.html;
}
location /_next/static/ {
expires 365d;
add_header Cache-Control "public, immutable";
}
}Wann was nutzen?
| Kriterium | Static Export | Server-Side Rendering |
|---|---|---|
| Node.js Server nötig? | ❌ Nein | ✅ Ja |
| API Routes | ❌ Nicht möglich | ✅ Ja |
| Dynamische Inhalte | Nur clientseitig | Server + Client |
| Server Components | ❌ Nein | ✅ Ja |
| ISR (Inkrementell) | ❌ Nein | ✅ Ja |
| Middleware | ❌ Nein | ✅ Ja |
| Performance | ⚡ Extrem schnell | 🚀 Schnell |
| Hosting-Kosten | 💰 Sehr günstig | 💰💰 Server nötig |
| Ideal für | Blogs, Docs, Landing Pages | Dashboards, E-Commerce, Apps |
✅ Faustregel: Wenn eure Seite keine serverseitigen Features braucht (API Routes, Server Components, Middleware, ISR), nutzt Static Export. Einfacher, schneller, günstiger. Für alles andere braucht ihr den Node.js Server.
Zusammenfassung & Checkliste
Hier die komplette Checkliste für euer Next.js Deployment:
- ☐ Node.js 22.x LTS installiert (NodeSource)
- ☐ next.config.js mit
output: 'standalone'konfiguriert - ☐ .env Dateien vorbereitet (Secrets nicht im Git!)
- ☐ Projekt auf Server gebracht (Git / rsync / SCP)
- ☐
npm ciundnpm run builderfolgreich - ☐ systemd Service erstellt und aktiviert
- ☐ Nginx Reverse Proxy konfiguriert
- ☐ SSL-Zertifikat mit Let’s Encrypt aktiv
- ☐ Firewall — nur Ports 80, 443, 22 offen
- ☐ Deployment-Script erstellt
- ☐ App unter
https://meinedomain.deerreichbar ✅
Troubleshooting
502 Bad Gateway
Der häufigste Fehler! Nginx kann den Next.js Server nicht erreichen.
# 1. Läuft der Service?
sudo systemctl status nextjs-meine-app
# 2. Auf welchem Port lauscht Next.js?
sudo ss -tlnp | grep node
# 3. Logs prüfen
sudo journalctl -u nextjs-meine-app --no-pager -n 50
# 4. Stimmt der Port in der Nginx-Config?
grep proxy_pass /etc/nginx/sites-available/meine-app
# Muss übereinstimmen!Port-Konflikte
# Wer belegt Port 3000?
sudo lsof -i :3000
# oder
sudo ss -tlnp | grep :3000
# Prozess beenden
sudo kill -9 <PID>
# Oder anderen Port nutzen:
# In der Service-Datei: Environment=PORT=3001
# In Nginx: proxy_pass http://127.0.0.1:3001;Build-Fehler
# Häufige Ursachen:
# 1. Nicht genug RAM (Build braucht ~1-2 GB)
free -h
# Lösung: Swap hinzufügen
sudo fallocate -l 2G /swapfile
sudo chmod 600 /swapfile
sudo mkswap /swapfile
sudo swapon /swapfile
echo '/swapfile swap swap defaults 0 0' | sudo tee -a /etc/fstab
# 2. Node.js Version zu alt
node --version
# Mindestens 18.18 für Next.js 15
# 3. Fehlende Umgebungsvariablen
# NEXT_PUBLIC_ Variablen müssen zur Build-Zeit vorhanden sein!
# Prüft eure .env.production
# 4. TypeScript-Fehler
# Build läuft im strict-Modus — alle Fehler müssen behoben werden
npm run build 2>&1 | head -50EACCES / Permission Denied
# Berechtigungen korrigieren
sudo chown -R www-data:www-data /var/www/meine-app
sudo chmod -R 755 /var/www/meine-app
# .next Ordner muss beschreibbar sein (für Cache)
sudo chmod -R 775 /var/www/meine-app/.nextNext.js startet, aber Seiten sind leer
# Bei Standalone: Static Assets fehlen!
cp -r public .next/standalone/public
cp -r .next/static .next/standalone/.next/static
# Service neustarten
sudo systemctl restart nextjs-meine-appNächste Schritte
Euer Next.js Deployment steht! Hier sind Ideen für weitere Optimierungen:
- CI/CD Pipeline — Automatisches Deployment mit GitHub Actions bei jedem Push
- Docker — Next.js in einem Container für noch einfacheres Deployment
- Monitoring — Server-Metriken mit Prometheus + Grafana überwachen
- CDN — Cloudflare oder ähnliches für globales Caching
- Datenbank — PostgreSQL oder MySQL auf dem gleichen Server einrichten
- Backups — Automatische Backups eurer App und Datenbank
- Rate Limiting — Nginx Rate Limiting gegen Missbrauch
Habt ihr Fragen oder Probleme? Schreibt es in die Kommentare!
Schreibe einen Kommentar