Ich verwende Nginx 0.7.64, Passenger 2.2.9, Rails 2.3.5. Mein Seiten-Caching-Verzeichnis ist auf /public/cache eingestellt und ich möchte in der Lage sein, zwischengespeicherte Seiten bereitzustellen, wenn sie über HTTP angefordert werden, aber immer die Rails-App aufrufen, wenn sie über HTTPS angefordert werden.
Der Großteil meiner Konfiguration sieht folgendermaßen aus:
server {
listen 80;
server_name website.com www.website.com;
proxy_set_header X-Forwarded-Proto http;
root /home/deploy/website/current/public;
passenger_enabled on;
if (-f $document_root/cache/$request_filename.html) {
rewrite (.*) $document_root/cache/$1.html break;
}
}
server {
listen 443;
server_name website.com www.website.com;
root /home/deploy/website/current/public;
passenger_enabled on;
proxy_set_header X-Forwarded-Proto https;
ssl on;
ssl_certificate /home/deploy/website/shared/ssl/www.website.com.combined.crt;
ssl_certificate_key /home/deploy/website/shared/ssl/www.website.com.key;
}
Ich gehe davon aus, dass mir bei einer Anforderung von website.com/about die Adresse /public/cache/about.html angezeigt werden sollte, stattdessen treffe ich jedoch auf den Rails-Server (ein Blick ins Protokoll zeigt dies).
Da ich dachte, ich hätte vielleicht einen unpassenden Schrägstrich (und sehe ihn $document_root
in den meisten Beispielen nicht), habe ich auch alle der folgenden Varianten ausprobiert, keine davon hat funktioniert:
if (-f cache$request_filename.html) {
rewrite (.*) cache$1.html break;
}
if (-f /cache$request_filename.html) {
rewrite (.*) /cache$1.html break;
}
if (-f cache/$request_filename.html) {
rewrite (.*) cache/$1.html break;
}
if (-f /cache/$request_filename.html) {
rewrite (.*) /cache/$1.html break;
}
Ich habe auch die Umschreiberegeln root
, , und in einen separaten Block geworfen, aber das funktioniert auch nicht. Ich habe auch die Anweisungen neu angeordnet, sodass dies am Ende kommt. Ich habe auch versucht, zu verwenden . Offensichtlich verstehe ich etwas falsch!passenger_enabled
location /
passenger_enabled
$uri
Dies ist etwas vereinfacht, da ich auch eine XML-API habe, die an bestimmten Stellen zwischengespeichert ist (vermutlich ist die Umschreibregel bis auf die .html
Teile dieselbe) und ich sie auch bereitstellen muss, public/cache/index.html
wenn die Wurzel website.com
angefordert wird. Ich möchte nur, dass jedes einzelne Teil davon funktioniert. :)
Jede Hilfe ist willkommen!
Aktualisieren
Der Konditional
if (-f $document_root/cache$request_uri.html)
Scheint zu funktionieren! Allerdings würde ich denken, dass das Umschreiben nicht funktioniert! Versuchen
if (-f $document_root/cache$request_uri.html) {
rewrite (.*) /cache$1.html break;
break;
}
Schreibt die URL um /cache/cache/about.html.html
und sendet sie an Rails, was sofort abstürzt. Es sieht doppelt aus, ja! Aber wenn ich es umschreibe, /cache$1
sendet es einfach /cache/cache/about
an Rails, und $1.html
sendet /about.html.html
an Rails, und $1
sendet einfach einfach /about
, was an Rails geht und den Cache nicht trifft. Offensichtlich ist das kein korrektes Verhalten. Schreibt Nginx es um und dann schreibt Passenger es auch um?
Antwort1
Die Antwort wurde hier gefunden: https://stackoverflow.com/questions/1177979/nginx-rewrite-rules-with-passenger
Die Konfiguration sah letztendlich so aus:
# root
if (-f $document_root/cache/$uri/index.html) {
rewrite (.*) /cache/$1/index.html break;
}
# pages like /about, cached with .html but accessed without
if (-f $document_root/cache/$uri.html) {
rewrite (.*) /cache/$1.html break;
}
# pages like /api/v1/something.xml, cached as xml
if (-f $document_root/cache/$uri) {
rewrite (.*) /cache/$1 break;
}
Antwort2
try_files
Ausführung:
server {
listen 80;
server_name website.com www.website.com;
location / {
root /home/deploy/website/current/public;
try_files $uri /cache/$uri/index.html /cache/$uri.html /cache/$uri @passenger;
}
location @passenger {
root /home/deploy/website/current/public;
proxy_set_header X-Forwarded-Proto http;
passenger_enabled on;
}
}
Beachten Sie, dass es mit Passenger möglicherweise funktioniert oder nicht. Ich bin mir jedoch sicher, dass es mit Unicorn, Mongrel usw. funktioniert.