- Image widths are 480, 720, 960, 1280, 1600 and 2400. A phone needed 721 pixels and got 960. Existing images receive the new steps from a task; stored pages pick them up at render time, so no document is rewritten. Mobile backgrounds use 720. - A variant served once is mirrored to public/media, and a rewrite rule lets the web server deliver it from there. var/media stays the source. - The hero preload follows the image each device really shows. - The post navigation reads the order and then two posts instead of up to 500 documents. Co-Authored-By: Claude Fable 5.2 <noreply@anthropic.com>
110 lines
5.6 KiB
ApacheConf
110 lines
5.6 KiB
ApacheConf
DirectoryIndex index.php
|
|
Options -Indexes -MultiViews
|
|
|
|
# Alles, was keine Datei ist, beantwortet PHP.
|
|
#
|
|
# Die Zeile fuer index.php selbst ist kein Zierrat: Bei IONOS erkennt !-f die bereits
|
|
# umgeschriebene index.php nicht als Datei, die Regel greift wieder und wieder, und Apache bricht
|
|
# nach zehn Runden mit einem weissen 500er ab (huefner-gartenbau.de, 12.10.2026). Dieselbe
|
|
# Absicherung steht in der .htaccess von WordPress.
|
|
RewriteEngine On
|
|
RewriteBase /
|
|
|
|
# HTTPS erzwingen. Auskommentiert, weil diese Datei auch in Installationen ohne Zertifikat
|
|
# liegt und eine Endlosschleife schlimmer waere als fehlendes HTTPS. Einschalten am besten in
|
|
# der Verwaltung unter System -> "HTTPS erzwingen": dort wird vorher und nachher geprueft und
|
|
# bei einer Schleife zurueckgenommen (ADR 120). Von Hand: die drei Zeilen einschalten - und erst
|
|
# danach die HSTS-Zeile weiter unten, denn HSTS laesst sich in einem Browser ein Jahr lang nicht
|
|
# zuruecknehmen.
|
|
#
|
|
# Die Zeilen stehen vor den Regeln fuer index.php, nicht dahinter: Nach dem Umschreiben auf
|
|
# index.php beginnt die Runde neu, und "^index\.php$ - [L]" beendet sie, bevor eine spaetere
|
|
# Regel an die Reihe kommt. Weiter unten griff die Umleitung nur fuer echte Dateien.
|
|
#RewriteCond %{HTTPS} !=on
|
|
#RewriteCond %{HTTP:X-Forwarded-Proto} !=https
|
|
#RewriteRule ^ https://%{HTTP_HOST}%{REQUEST_URI} [R=301,L]
|
|
|
|
# Bilder der Mediathek ohne PHP ausliefern (ADR 129).
|
|
#
|
|
# Ein Bild heisst /media/<kennung>/<breite>. Liegt die Variante im Abbild public/media/ - dort legt
|
|
# die Anwendung sie beim ersten Abruf ab -, beantwortet der Webserver die Anfrage selbst: kein
|
|
# PHP-Prozess, keine Datenbank. Fehlt sie, greift die Regel nicht, und alles laeuft wie bisher
|
|
# ueber index.php. Die Pruefung haengt an REQUEST_FILENAME wie die Regel darunter; nach dem
|
|
# Umschreiben endet die Adresse auf .webp und passt nicht noch einmal.
|
|
RewriteCond %{REQUEST_FILENAME}.webp -f
|
|
RewriteRule ^media/[a-f0-9]{32}/[0-9]{1,4}$ %{REQUEST_URI}.webp [L]
|
|
|
|
RewriteRule ^index\.php$ - [L]
|
|
RewriteCond %{REQUEST_FILENAME} !-f
|
|
RewriteRule ^ index.php [L]
|
|
|
|
# Eine Domain, eine Adresse - mit oder ohne www. Das erledigt die Anwendung selbst nach der
|
|
# Einstellung SITE_ORIGIN in .env: die jeweils andere Schreibweise antwortet mit 301 dorthin.
|
|
# Hier braucht es dafuer keine Regel; eine zweite Stelle wuerde nur auseinanderlaufen.
|
|
|
|
# Uebertragen wird komprimiert. HTML, CSS, JavaScript und XML schrumpfen dabei auf etwa ein
|
|
# Viertel; Bilder und Schriften sind bereits komprimiert und bleiben aussen vor.
|
|
<IfModule mod_deflate.c>
|
|
AddOutputFilterByType DEFLATE text/html text/plain text/xml text/css
|
|
AddOutputFilterByType DEFLATE application/javascript application/json application/xml
|
|
AddOutputFilterByType DEFLATE application/rss+xml image/svg+xml
|
|
</IfModule>
|
|
<IfModule mod_brotli.c>
|
|
AddOutputFilterByType BROTLI_COMPRESS text/html text/css application/javascript image/svg+xml
|
|
</IfModule>
|
|
|
|
# Wie lange ein Browser eine Datei behalten darf.
|
|
#
|
|
# Bilder und Schriften tragen ihre Kennung im Namen: aendert sich der Inhalt, aendert sich die
|
|
# Adresse. Sie duerfen deshalb ein Jahr bleiben. Stylesheets und Skripte tragen die Fassung als
|
|
# Parameter, also ebenfalls ein Jahr. HTML wird nie zwischengespeichert - eine veroeffentlichte
|
|
# Aenderung soll beim naechsten Aufruf sichtbar sein; die Seiten senden dafuer selbst no-store.
|
|
# Aeltere Server kennen die Endung nicht und lieferten die Bilder des Abbilds als Text aus.
|
|
<IfModule mod_mime.c>
|
|
AddType image/webp .webp
|
|
</IfModule>
|
|
<IfModule mod_expires.c>
|
|
ExpiresActive On
|
|
ExpiresByType image/webp "access plus 1 year"
|
|
ExpiresByType image/png "access plus 1 year"
|
|
ExpiresByType image/jpeg "access plus 1 year"
|
|
ExpiresByType image/svg+xml "access plus 1 year"
|
|
ExpiresByType font/woff2 "access plus 1 year"
|
|
ExpiresByType text/css "access plus 1 year"
|
|
ExpiresByType application/javascript "access plus 1 year"
|
|
</IfModule>
|
|
<IfModule mod_headers.c>
|
|
<FilesMatch "\.(webp|png|jpe?g|gif|svg|woff2|css|js)$">
|
|
Header set Cache-Control "public, max-age=31536000, immutable"
|
|
</FilesMatch>
|
|
# Schriften werden von derselben Adresse geladen; die Regel steht hier, damit sie auch dann
|
|
# gilt, wenn eine Installation die Dateien ueber ein CDN spiegelt.
|
|
<FilesMatch "\.woff2$">
|
|
Header set Access-Control-Allow-Origin "*"
|
|
</FilesMatch>
|
|
# Dieselbe Zeile, die die Anwendung an ein Bild haengt, wenn sie es selbst ausliefert.
|
|
<FilesMatch "\.webp$">
|
|
Header set X-Content-Type-Options "nosniff"
|
|
</FilesMatch>
|
|
# Was der Server ueber sich selbst erzaehlt, geht niemanden etwas an: die genaue PHP-Fassung
|
|
# ist fuer einen Besucher wertlos und fuer einen Scanner eine Einkaufsliste.
|
|
Header always unset X-Powered-By
|
|
Header always unset X-AspNet-Version
|
|
# Erst einschalten, wenn HTTPS steht und bleiben soll (siehe oben; System -> HSTS).
|
|
#Header always set Strict-Transport-Security "max-age=31536000; includeSubDomains"
|
|
</IfModule>
|
|
|
|
# Nichts ausliefern, was nur intern gebraucht wird - falls jemand das Paket versehentlich
|
|
# vollstaendig in den oeffentlichen Ordner legt statt nur public/.
|
|
# .well-known ausgenommen: Zertifikatsanbieter (acme-challenge) brauchen den Ordner, und Apache
|
|
# prueft den ersten nicht vorhandenen Pfadteil gegen diese Regel. Die Probe der Verwaltung
|
|
# (Adresse speichern, HTTPS erzwingen) liegt nicht mehr dort, sondern unter /kantsites-origin:
|
|
# IONOS beantwortet /.well-known/ selbst mit 403 (ADR 122).
|
|
<FilesMatch "^\.(?!well-known$)|\.(env|db|sqlite|lock|md|yaml|yml|dist|log)$">
|
|
Require all denied
|
|
</FilesMatch>
|
|
# Eine Ausnahme mit Grund: der Editor liest die Liste der Gestaltungswerte als JSON.
|
|
<Files "design-tokens.json">
|
|
Require all granted
|
|
</Files>
|