Wie Sie alle vorhandenen statischen Dateien direkt mit NGINX bereitstellen, den Rest jedoch an einen Back-End-Server übertragen.

84
location / {
    proxy_set_header X-Real-IP  $remote_addr;
    proxy_set_header Host $host;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;

    if (-f $request_filename) {
        access_log off;
        expires 30d;
        break;
        }

    if (!-f $request_filename) {
        proxy_pass http://127.0.0.1:8080; # backend server listening
        break;
        }
    }

Oben werden alle vorhandenen Dateien direkt mit Nginx bereitgestellt (z. B. zeigt Nginx nur PHP-Quellcode an), andernfalls wird eine Anfrage an Apache weitergeleitet. Ich muss * .php-Dateien von der Regel ausschließen, damit Anforderungen für * .php auch an Apache übergeben und verarbeitet werden.

Ich möchte, dass Nginx alle statischen Dateien verarbeitet und Apache alle dynamischen Dateien verarbeitet.

EDIT: Es gibt einen White-List-Ansatz, aber er ist nicht sehr elegant. Sehen Sie all diese Erweiterungen, ich möchte das nicht.

location ~* ^.+.(jpg|jpeg|gif|png|ico|css|zip|tgz|gz|rar|bz2|doc|xls|exe|pdf|ppt|txt|tar|mid|midi|wav|bmp|rtf|js)$ {
    access_log off;
    expires 30d;
    }
location / {
    proxy_set_header X-Real-IP  $remote_addr;
    proxy_set_header Host $host;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_pass http://127.0.0.1:8080;
    }

BEARBEITEN 2: Verwenden Sie in neueren Versionen von Nginx try_filesstattdessen http://wiki.nginx.org/HttpCoreModule#try_files

Fmalina
quelle
Nur um die Dinge zu löschen: Der obige Code dient als statische Datei, wenn er auf der Festplatte vorhanden ist. Wenn die Datei nicht vorhanden ist, wird die Anforderung an Apache übergeben. Dies funktioniert meistens, da alle URLs in meinen Anwendungen mod_rewrite (oder Routing) verwenden und nicht wirklich auf der Festplatte vorhanden sind. Nur der direkte Zugriff auf den Dateinamen * .php ist eine Ausnahme und muss von Apache analysiert werden.
Fmalina

Antworten:

149

Verwenden Sie try_files und den benannten Standortblock ('@apachesite'). Dadurch werden unnötige Regex-Übereinstimmungen und if-Blöcke entfernt. Effizienter.

location / {
    root /path/to/root/of/static/files;
    try_files $uri $uri/ @apachesite;

    expires max;
    access_log off;
}

location @apachesite {
    proxy_set_header X-Real-IP  $remote_addr;
    proxy_set_header Host $host;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_pass http://127.0.0.1:8080;
}

Update: Die Annahme dieser Konfiguration ist, dass es kein PHP-Skript unter gibt /path/to/root/of/static/files. Dies ist in den meisten modernen PHP-Frameworks üblich. Wenn in Ihren älteren PHP-Projekten sowohl PHP-Skripte als auch statische Dateien im selben Ordner gemischt sind, müssen Sie möglicherweise alle Dateitypen auf die Whitelist setzen, die Nginx bereitstellen soll.

Chuan Ma
quelle
Ich verwende WordPress. Sollte ich also einen Upload-Ordner auf dem Nginx-Server ablegen müssen?
Chameron
7
Mein Problem mit dieser Lösung: nginx verwendet nicht den anderen Speicherort (den Proxy) und versucht, die Verzeichnisliste anzuzeigen. Es wird also ein 403 ausgelöst, da die Verzeichnisliste nicht aktiviert ist. Bearbeiten: Ok, wenn Sie entfernen, $uri/dann funktioniert es.
ChristophLSA
1
Dies würde Proxy / Beispiel für Apache sein, aber das Herunterladen von /example.php ermöglichen.
Terence Johnson
1
@TerenceJohnson Es ist nicht sicher, Ihre PHP-Dateien im statischen Dateiordner abzulegen. Beachten Sie, dass ich eingestellt habe root /path/to/root/of/*static*/files;. PHP-Dateien sollten in einem anderen Ordner abgelegt werden, auf den nicht direkt über das Internet zugegriffen werden kann.
Chuan Ma
2
Ich weiß, dass die Dinge so sein sollten, aber wenn jemand Nginx vor eine der vielen gängigen Standard-PHP-Anwendungen stellt, die alles unter dem Webstamm haben und sich auf .htaccess-Dateien verlassen, sollten sie nicht kopieren und Fügen Sie Ihre Konfiguration ein.
Terence Johnson
18

Versuche dies:

location / {
    root /path/to/root;
    expires 30d;
    access_log off;
}

location ~* ^.*\.php$ {
    if (!-f $request_filename) {
        return 404;
    }
    proxy_set_header X-Real-IP  $remote_addr;
    proxy_set_header Host $host;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_pass http://127.0.0.1:8080;
}

Hoffentlich funktioniert es. Reguläre Ausdrücke haben eine höhere Priorität als einfache Zeichenfolgen. .phpDaher sollten alle Anforderungen, die mit enden, an Apache weitergeleitet werden, wenn nur eine entsprechende .phpDatei vorhanden ist. Rest wird als statische Dateien behandelt. Der eigentliche Algorithmus zur Standortbewertung ist hier .

Jasiu
quelle
6

Wenn Sie mod_rewrite verwenden, um die Erweiterung Ihrer Skripte auszublenden, oder wenn Sie nur hübsche URLs mögen, die mit / enden, möchten Sie dies möglicherweise aus der anderen Richtung betrachten. Sagen Sie nginx, dass alles mit einer nicht statischen Erweiterung zu Apache gehen soll. Beispielsweise:

location ~* ^.+\.(jpg|jpeg|gif|png|ico|css|zip|tgz|gz|rar|bz2|pdf|txt|tar|wav|bmp|rtf|js|flv|swf|html|htm)$
{
    root   /path/to/static-content;
}

location ~* ^!.+\.(jpg|jpeg|gif|png|ico|css|zip|tgz|gz|rar|bz2|pdf|txt|tar|wav|bmp|rtf|js|flv|swf|html|htm)$ {
    if (!-f $request_filename) {
        return 404;
    }
    proxy_set_header X-Real-IP  $remote_addr;
    proxy_set_header Host $host;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_pass http://127.0.0.1:8080;
}

Ich fand den ersten Teil dieses Snippets unter: http://code.google.com/p/scalr/wiki/NginxStatic

lo_fye
quelle
Dies hat großartig funktioniert, obwohl ich immer noch Fehler für minimierte Dateien bekomme (z. B. site.min.css und main.min.js usw.). Wie würde ich diese in einem Standort-Regex fangen? @lo_fye
Garth