Bereitstellung statischer Dateien mit Nginx: Optimierungstipps
Optimieren Sie die Auslieferung statischer Dateien mit Nginx durch korrekte Cache-Header, Gzip-Komprimierung, sichere Standardeinstellungen und Tipps zum Schutz versteckter Dateien – für schnellere Websites mit weniger Problemen durch veraltete Assets.
Bereitstellung statischer Dateien mit Nginx: Optimierungstipps
Die Bereitstellung statischer Dateien mit Nginx ist eine der gängigsten und effizientesten Methoden, um Bilder, CSS, JavaScript, Downloads und gebaute Frontend-Assets auszuliefern. Nginx ist sehr gut in dieser Aufgabe, aber einige Konfigurationsentscheidungen können den Unterschied zwischen einer schnellen, vorhersagbaren Website und einer, die Bandbreite verschwendet oder veraltete Inhalte ausliefert, ausmachen.
Die Optimierung statischer Dateien dreht sich hauptsächlich um klare Pfade, korrekte Caching-Header, Komprimierung und sichere Standardeinstellungen. Sie benötigen kein kompliziertes Setup, um gute Ergebnisse zu erzielen, aber die Cache-Regeln müssen dazu passen, wie Ihre Dateien benannt und bereitgestellt werden.
Beginnen Sie mit einem klaren Speicherort für statische Dateien
Das einfachste Setup für statische Dateien verwendet root und try_files:
server {
listen 80;
server_name example.com;
root /var/www/example.com/public;
index index.html;
location / {
try_files $uri $uri/ =404;
}
}
Mit dieser Konfiguration wird eine Anfrage für /css/app.css auf /var/www/example.com/public/css/app.css abgebildet. Wenn die Datei nicht existiert, gibt Nginx 404 zurück.
Diese direkte Zuordnung ist nützlich, wenn Sie debuggen. Sie können eine URL aus dem Browser nehmen, in einen Dateisystempfad umwandeln und prüfen, ob die Datei existiert:
ls -l /var/www/example.com/public/css/app.css
Wenn die Datei existiert, Nginx aber 404 zurückgibt, suchen Sie nach einem anderen root, einem spezifischeren location-Block oder einer Include-Datei, die den Pfad überschreibt.
Für eine Single-Page-App möchten Sie möglicherweise, dass unbekannte Routen auf index.html zurückfallen:
location / {
try_files $uri $uri/ /index.html;
}
Das ist nützlich für Frontend-Router, aber verwenden Sie es nicht blind für jede Website. Wenn fehlende Assets ebenfalls index.html zurückgeben, kann das Debuggen von defekten JavaScript- oder Bildpfaden verwirrend werden. Viele Teams verwenden einen separaten Speicherort für Assets, sodass fehlende Dateien weiterhin einen echten 404 zurückgeben.
Sie können auch alias verwenden, wenn ein URL-Pfad auf einen anderen Dateisystempfad abgebildet werden soll:
location /assets/ {
alias /srv/shared-assets/;
}
Seien Sie vorsichtig mit abschließenden Schrägstrichen. Bei alias sollten der Location-Pfad und der Dateisystempfad normalerweise beide mit / enden. Eine Nichtübereinstimmung kann unerwartete Dateipfade erzeugen.
Ein sicheres Muster ist:
location /downloads/ {
alias /srv/downloads/;
try_files $uri =404;
}
Hier wird /downloads/manual.pdf auf /srv/downloads/manual.pdf abgebildet. Ohne die Disziplin des abschließenden Schrägstrichs kann es leicht passieren, dass Sie versehentlich Pfade erstellen, die nicht existieren, oder ein Verzeichnis freigeben, das Sie nicht veröffentlichen wollten.
Für einen tieferen Einblick in das Matching-Verhalten siehe Nginx location blocks.
Browser-Caching-Header hinzufügen
Statische Dateien sind hervorragende Kandidaten für Browser-Caching. Wenn ein Benutzer app.css einmal herunterlädt, sollte der Browser es nicht bei jedem Seitenaufruf erneut abrufen, es sei denn, es hat sich geändert.
Für versionierte Assets verwenden Sie lange Cache-Laufzeiten:
location /assets/ {
root /var/www/example.com/public;
expires 1y;
add_header Cache-Control "public, immutable";
}
Dies funktioniert am besten, wenn sich Dateinamen während der Bereitstellung ändern, wie z.B. app.8f3a91.css oder bundle.20260523.js. Wenn sich der Dateiname ändert, wenn sich der Inhalt ändert, können Browser die alte Datei sicher für lange Zeit zwischenspeichern.
Für Dateien, die denselben Namen behalten, verwenden Sie kürzeres Caching:
location = /index.html {
root /var/www/example.com/public;
expires -1;
add_header Cache-Control "no-cache";
}
Dieses Muster ist bei Frontend-Apps üblich. Die HTML-Datei bleibt frisch, während gehashte CSS- und JavaScript-Dateien aggressiv gecached werden.
Ein praktisches Beispiel: Ihre React- oder Vue-Build-Ausgabe erzeugt gehashte Assets in /assets/ und eine einfache index.html. Cachen Sie /assets/ für ein Jahr, aber lassen Sie index.html erneut validieren. Benutzer erhalten schnelle wiederholte Besuche, und neue Bereitstellungen laden dennoch die neuesten Asset-Referenzen.
Nachdem Sie die Cache-Regeln geändert haben, testen Sie die Header, anstatt zu raten:
curl -I https://example.com/assets/app.8f3a91.css
curl -I https://example.com/
Sie möchten, dass das gehashte Asset einen langlebigen Cache-Control-Wert anzeigt. Normalerweise möchten Sie, dass die HTML-Seite erneut validiert oder eine kurze Lebensdauer verwendet. Wenn beide für ein Jahr gecached werden, kann eine Bereitstellung Benutzer auf einer alten HTML-Datei festsitzen lassen, die auf altes JavaScript verweist.
Komprimierung für Text-Assets verwenden
Text-Assets wie CSS, JavaScript, SVG und JSON lassen sich gut komprimieren. Sie können Gzip im http-Block aktivieren:
gzip on;
gzip_comp_level 5;
gzip_min_length 1024;
gzip_vary on;
gzip_types
text/css
application/javascript
application/json
image/svg+xml;
Erwarten Sie nicht, dass Gzip bei JPEG, PNG, WebP, MP4 oder Zip-Dateien viel hilft. Diese Formate sind bereits komprimiert. Der Versuch, sie erneut zu komprimieren, verschwendet normalerweise CPU.
Für stark frequentierte statische Websites sollten Sie vorcompilierte Dateien in Betracht ziehen. Ihr Build-Prozess kann .gz-Versionen großer CSS- und JavaScript-Dateien erstellen, und Nginx kann sie ausliefern, wenn der Browser Gzip unterstützt:
gzip_static on;
Dies reduziert die Laufzeitkomprimierungsarbeit, da Nginx die vorcompilierte Datei von der Festplatte liest. Es ist am nützlichsten, wenn Assets im Voraus erstellt werden und sich zwischen den Anfragen nicht ändern.
Komprimierung ist nur ein Teil der Asset-Auslieferung. Die Dateigröße ist immer noch wichtig. Entfernen Sie ungenutztes JavaScript, optimieren Sie Bilder während Ihres Build-Prozesses und vermeiden Sie es, große Dateien auszuliefern, die Benutzer nicht benötigen.
Wenn Sie die Komprimierung testen, fügen Sie einen Accept-Encoding-Header hinzu:
curl -I -H 'Accept-Encoding: gzip' https://example.com/assets/app.js
Achten Sie auf Content-Encoding: gzip und Vary: Accept-Encoding. Der Vary-Header ist wichtig, wenn ein CDN oder ein gemeinsam genutzter Cache vor Nginx sitzt, da komprimierte und unkomprimierte Antworten nicht vermischt werden dürfen.
Dateiauslieferung und Sicherheit verbessern
Nginx kann statische Dateien mit Standardeinstellungen effizient ausliefern, aber einige Details helfen in der Produktion.
Erstens deaktivieren Sie Verzeichnislisten, es sei denn, Sie benötigen sie explizit:
autoindex off;
Verzeichnislisten können Dateinamen und Strukturen preisgeben, die Sie nicht veröffentlichen wollten.
Zweitens blockieren Sie den Zugriff auf versteckte Dateien wie .env, .git und andere Punktdateien:
location ~ /\.(?!well-known) {
deny all;
}
Die Ausnahme für .well-known ist üblich, da Zertifikatsvalidierung und standardbasierte Dateien dieses Verzeichnis verwenden können.
Drittens stellen Sie sicher, dass Ihre statischen Dateiberechtigungen es Nginx erlauben, Dateien zu lesen, aber dem Webserver keine unnötigen Schreibrechte geben. Ein typisches Setup ermöglicht es Bereitstellungstools, Dateien zu schreiben, und dem Nginx-Worker-Benutzer, sie zu lesen.
Viertens überprüfen Sie die MIME-Typen. Nginx enthält normalerweise eine mime.types-Datei, aber abgespeckte Container oder benutzerdefinierte Builds können sie vermissen lassen. Wenn CSS als text/plain ausgeliefert wird, können Browser es ablehnen oder sich anders verhalten.
Verwenden Sie:
include /etc/nginx/mime.types;
default_type application/octet-stream;
Überwachen Sie schließlich die Logs auf wiederholte 404-Antworten bei Assets. Das bedeutet oft, dass eine Bereitstellung auf Dateien verweist, die nicht existieren, ein Cache immer noch auf einen alten Dateinamen zeigt oder ein alias-Pfad falsch ist.
Wenn die statische Auslieferung langsam erscheint, beginnen Sie nicht damit, jede Tuning-Direktive zu kopieren, die Sie finden können. Überprüfen Sie zuerst, ob das Problem tatsächlich Nginx ist. Große Bilder, unoptimierte Frontend-Bundles, entfernte Speicher-Mounts und CDN-Cache-Fehlschläge sind häufigere Ursachen als eine fehlende Mikrooptimierung im Server-Block.
Für eine schnelle lokale Überprüfung:
curl -o /dev/null -s -w 'status=%{http_code} size=%{size_download} time=%{time_total}\n' https://example.com/assets/app.js
Vergleichen Sie dies dann mit CDN-Logs, Browser-Entwicklertools oder einer Anfrage aus derselben Region wie Ihre Benutzer. Eine schnelle Antwort von Nginx und eine langsame Antwort im Browser deuten normalerweise auf etwas anderes im Auslieferungspfad hin.
Wann Sie Hilfe holen sollten
Holen Sie einen DevOps-Ingenieur hinzu, wenn Ihre statischen Dateien von gemeinsam genutztem Speicher, gemounteten Volumes, Objektspeicher-Gateways oder einem CDN vor Nginx ausgeliefert werden. Die beste Caching-Strategie hängt vom gesamten Auslieferungspfad ab, nicht nur vom Nginx-Server-Block.
Sie sollten auch Hilfe holen, wenn Benutzer nach Bereitstellungen veraltetes JavaScript melden. Das bedeutet normalerweise, dass die Cache-Regeln und die Dateinamen-Versionierungsstrategie nicht zusammenpassen.
Die Bereitstellung statischer Dateien mit Nginx funktioniert am besten, wenn Pfade vorhersagbar sind, Cache-Laufzeiten zur Dateinamen-Strategie passen und Text-Assets komprimiert werden. Halten Sie fehlende Dateien sichtbar, schützen Sie versteckte Dateien und testen Sie Header nach jeder Konfigurationsänderung. Ein sauberes statisches Setup macht Ihre Website schneller, ohne bewegliche Teile hinzuzufügen.