Zum Hauptinhalt springen

Nginx-Konfiguration

Vollständige Nginx-Einrichtungsanleitung für FeedbackPulse SaaS.


Voraussetzungen

  • Nginx 1.18+
  • PHP-FPM 8.4+
  • SSL-Zertifikat (empfohlen)

Einfacher Server-Block

Neue Nginx-Konfiguration erstellen:

sudo nano /etc/nginx/sites-available/feedbackpulse

Folgendes einfügen:

server {
listen 80;
listen [::]:80;
server_name yourdomain.com www.yourdomain.com;
root /var/www/feedbackpulse-saas/public;

index index.php index.html;

charset utf-8;

# Laravel URL-Rewriting
location / {
try_files $uri $uri/ /index.php?$query_string;
}

# PHP-Verarbeitung
location ~ \.php$ {
fastcgi_pass unix:/var/run/php/php8.4-fpm.sock;
fastcgi_param SCRIPT_FILENAME $realpath_root$fastcgi_script_name;
include fastcgi_params;
fastcgi_hide_header X-Powered-By;
}

# Zugriff auf versteckte Dateien verweigern
location ~ /\.(?!well-known).* {
deny all;
}

# Statisches Datei-Caching
location ~* \.(jpg|jpeg|png|gif|ico|css|js|svg|woff|woff2|ttf|eot)$ {
expires 30d;
add_header Cache-Control "public, immutable";
}

# Maximale Upload-Größe (für Fotos, Logos)
client_max_body_size 20M;

# Protokollierung
access_log /var/log/nginx/feedbackpulse-access.log;
error_log /var/log/nginx/feedbackpulse-error.log;
}

Site aktivieren:

sudo ln -s /etc/nginx/sites-available/feedbackpulse /etc/nginx/sites-enabled/
sudo rm /etc/nginx/sites-enabled/default # Standard-Site entfernen (optional)
sudo nginx -t # Konfiguration testen
sudo systemctl restart nginx

HTTPS Server-Block (mit Let's Encrypt)

# HTTP auf HTTPS umleiten
server {
listen 80;
listen [::]:80;
server_name yourdomain.com www.yourdomain.com;
return 301 https://yourdomain.com$request_uri;
}

# Haupt-HTTPS-Server
server {
listen 443 ssl http2;
listen [::]:443 ssl http2;
server_name yourdomain.com www.yourdomain.com;
root /var/www/feedbackpulse-saas/public;

index index.php index.html;
charset utf-8;

# SSL-Konfiguration
ssl_certificate /etc/letsencrypt/live/yourdomain.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/yourdomain.com/privkey.pem;
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384;
ssl_prefer_server_ciphers off;

# 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 Strict-Transport-Security "max-age=31536000; includeSubDomains" always;
add_header Referrer-Policy "strict-origin-when-cross-origin" always;

# Laravel URL-Rewriting
location / {
try_files $uri $uri/ /index.php?$query_string;
}

# PHP-Verarbeitung
location ~ \.php$ {
fastcgi_pass unix:/var/run/php/php8.4-fpm.sock;
fastcgi_param SCRIPT_FILENAME $realpath_root$fastcgi_script_name;
include fastcgi_params;
fastcgi_hide_header X-Powered-By;
fastcgi_read_timeout 300;
}

# Zugriff auf versteckte Dateien verweigern (außer .well-known für ACME)
location ~ /\.(?!well-known).* {
deny all;
}

# Statisches Datei-Caching
location ~* \.(jpg|jpeg|png|gif|ico|css|js|svg|woff|woff2|ttf|eot)$ {
expires 30d;
add_header Cache-Control "public, immutable";
}

client_max_body_size 20M;

access_log /var/log/nginx/feedbackpulse-access.log;
error_log /var/log/nginx/feedbackpulse-error.log;
}

Wildcard-Subdomain-Unterstützung

Für Mandanten-Subdomains wie acme.yourdomain.com:

server {
listen 443 ssl http2;
listen [::]:443 ssl http2;
server_name yourdomain.com *.yourdomain.com;
root /var/www/feedbackpulse-saas/public;

# Ein Wildcard-SSL-Zertifikat verwenden
ssl_certificate /etc/letsencrypt/live/yourdomain.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/yourdomain.com/privkey.pem;

# ... Rest der Konfiguration wie im HTTPS-Block oben ...

index index.php index.html;
charset utf-8;

location / {
try_files $uri $uri/ /index.php?$query_string;
}

location ~ \.php$ {
fastcgi_pass unix:/var/run/php/php8.4-fpm.sock;
fastcgi_param SCRIPT_FILENAME $realpath_root$fastcgi_script_name;
include fastcgi_params;
fastcgi_hide_header X-Powered-By;
}

location ~ /\.(?!well-known).* {
deny all;
}

client_max_body_size 20M;
}

Erforderlich: Wildcard-DNS-Eintrag + Wildcard-SSL-Zertifikat. Siehe Wildcard-DNS-Setup.


PHP-FPM-Konfiguration

PHP-FPM für FeedbackPulse optimieren:

sudo nano /etc/php/8.4/fpm/pool.d/www.conf

Wichtige Einstellungen:

; Prozessverwaltung
pm = dynamic
pm.max_children = 20
pm.start_servers = 5
pm.min_spare_servers = 3
pm.max_spare_servers = 10
pm.max_requests = 500

; Timeouts
request_terminate_timeout = 300

; Upload-Limits
php_admin_value[upload_max_filesize] = 20M
php_admin_value[post_max_size] = 25M
php_admin_value[memory_limit] = 256M

PHP-FPM neu starten:

sudo systemctl restart php8.4-fpm

Laravel Forge / Ploi / RunCloud

Falls Sie einen verwalteten Server-Anbieter nutzen:

Laravel Forge

  1. Eine neue Site mit der Domain yourdomain.com erstellen
  2. Web-Verzeichnis auf /public setzen
  3. Code deployen (Git oder Upload)
  4. Forge konfiguriert Nginx automatisch korrekt
  5. SSL über den Reiter „SSL" aktivieren (Let's Encrypt)

Ploi

  1. Neue Site hinzufügen → Domain eingeben
  2. Root auf /public setzen
  3. Code deployen
  4. SSL wird automatisch konfiguriert

RunCloud

  1. Web-App erstellen → „PHP" auswählen → Domain eingeben
  2. Public-Pfad auf public setzen
  3. Via Git oder Dateimanager deployen
  4. SSL aktivieren

Nginx-Konfiguration prüfen

# Syntax testen
sudo nginx -t

# Prüfen ob PHP-FPM läuft
sudo systemctl status php8.4-fpm

# Prüfen ob Nginx läuft
sudo systemctl status nginx

# Prüfen welcher PHP-FPM-Socket verwendet wird
ls /var/run/php/

# Alles neu starten
sudo systemctl restart php8.4-fpm nginx

Häufige Nginx-Probleme

ProblemLösung
502 Bad GatewayPHP-FPM läuft nicht oder Socket-Pfad ist falsch. Prüfen Sie, ob fastcgi_pass mit Ihrem PHP-FPM-Socket übereinstimmt.
404 bei allen RoutenFehlende try_files $uri $uri/ /index.php?$query_string; im Location-Block.
413 Request Entity Too Largeclient_max_body_size erhöhen (Standard ist 1 MB).
„File not found"Prüfen, ob root auf das public/-Verzeichnis zeigt und $realpath_root in SCRIPT_FILENAME verwendet wird.
Leere Seitestorage/logs/laravel.log und /var/log/nginx/feedbackpulse-error.log prüfen.

Nächste Schritte