Nginx - statische Datei, die mit root & alias verwechselt wird

473

Ich muss meine App über meinen App-Server unter 8080und meine statischen Dateien aus einem Verzeichnis bereitstellen, ohne den App-Server zu berühren. Die Nginx-Konfiguration, die ich habe, ist ungefähr so ​​...

    # app server on port 8080
    # nginx listens on port 8123
    server {
            listen          8123;
            access_log      off;

            location /static/ {
                    # root /var/www/app/static/;
                    alias /var/www/app/static/;
                    autoindex off;
            }


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

Mit dieser Konfiguration funktioniert jetzt alles einwandfrei. Beachten Sie, dass die rootRichtlinie auskommentiert ist.

Wenn ich das aktiviere rootund deaktiviere, aliasfunktioniert es nicht mehr. Wenn ich jedoch das Trailing /static/von dem entferne, rootfunktioniert es wieder.

Kann jemand erklären, was los ist. Bitte erläutern Sie auch klar und ausführlich, was die Unterschiede zwischen rootund aliasund deren Zweck sind.

Baumkodierer
quelle

Antworten:

1074

Ich habe Antworten auf meine Verwirrungen gefunden.

Es gibt einen sehr wichtigen Unterschied zwischen der rootund der aliasRichtlinie. Dieser Unterschied besteht in der Art und Weise, wie der im rootoder im angegebene Pfad aliasverarbeitet wird.

Bei der rootDirektive wird der vollständige Pfad an den Stamm einschließlich des Positionsteils angehängt , während bei der aliasDirektive nur der Teil des Pfads, der den Positionsteil NICHT enthält, an den Alias ​​angehängt wird .

Um zu zeigen:

Nehmen wir an, wir haben die Konfiguration

location /static/ {
    root /var/www/app/static/;
    autoindex off;
}

In diesem Fall ist der endgültige Pfad, den Nginx ableiten wird

/var/www/app/static/static

Dies wird zurückkehren, 404da es kein static/Inneres gibtstatic/

Dies liegt daran, dass der Positionsteil an den in der angegebenen Pfad angehängt wird root. Daher ist mit rootder richtige Weg

location /static/ {
    root /var/www/app/;
    autoindex off;
}

Auf der anderen Seite wird mit aliasder Positionsteil gelöscht . Also für die Konfiguration

location /static/ {
    alias /var/www/app/static/;
    autoindex off;           ↑
}                            |
                             pay attention to this trailing slash

Der endgültige Pfad wird korrekt als gebildet

/var/www/app/static

Der Fall eines abschließenden Schrägstrichs für die aliasRichtlinie

Es gibt keine endgültige Richtlinie darüber, ob ein abschließender Schrägstrich gemäß der Nginx-Dokumentation obligatorisch ist , aber eine häufige Beobachtung von Personen hier und anderswo scheint darauf hinzudeuten, dass dies der Fall ist.

Einige weitere Stellen haben dies diskutiert, jedoch nicht abschließend.

/server/376162/how-can-i-create-a-location-in-nginx-that-works-with-and-without-a-trailing-slas

/server/375602/why-is-my-nginx-alias-not-working

Baumkodierer
quelle
97
Der abschließende Schrägstrich auf dem Alias-Pfad ist unerlässlich!
Mafrose
2
Das ist alles großartig (es hat mir geholfen, meine Konfigurationsprobleme zu beheben), aber ich frage mich, welche Protokollierungseinstellungen die Benutzer zur Diagnose dieser Art von Problemen verwenden könnten. Wie alles, was in Protokollen gedruckt werden würde, wie "empfangene Anfrage für [...] empfangen, abgeglichen mit" Ort [...] "Konfigurationsblock,
Suchverzeichnis
2
@ Pistos: log_format scripts '$document_root | $uri | > $request';in httpAbschnitt und access_log /var/log/nginx/scripts.log scripts;in serverAbschnitt der Nginx-Konfiguration setzen ..
Helvete
Vielen Dank! In der Tat ist der abschließende Schrägstrich für den Alias ​​wichtig, sonst habe ich ihn bekommen nginx: [emerg] invalid number of arguments in "alias" directive, und der Server ist während seines Neustarts ausgefallen.
FotisK
@mafrosis Warum ist es wichtig?
Bruce Sun
104

wie sagen als @treecoder

Bei der rootDirektive wird der vollständige Pfad an den Stamm einschließlich des Positionsteils angehängt, während bei der aliasDirektive nur der Teil des Pfads, der den Positionsteil NICHT enthält, an den Alias ​​angehängt wird.

Ein Bild sagt mehr als tausend Worte

für root:

Geben Sie hier die Bildbeschreibung ein

für alias:

Geben Sie hier die Bildbeschreibung ein

liuzhijun
quelle
11
Sollte der erste Pfeil im zweiten Bild ein "+" sein?
Aioobe
35

In Ihrem Fall können Sie die rootDirektive verwenden, da ein $uriTeil der locationDirektive mit dem letzten rootDirektiventeil identisch ist .

Die Nginx-Dokumentation empfiehlt dies ebenfalls:
Wenn der Speicherort mit dem letzten Teil des Werts der Direktive übereinstimmt:

location /images/ {
    alias /data/w3/images/;
}

Es ist besser, stattdessen die Root-Direktive zu verwenden:

location /images/ {
    root /data/w3;
}

und rootDirektive wird $urian den Pfad angehängt .

antonbormotov
quelle
2
Warum ist es besser? Docs sagen es auch nicht.
HostedMetrics.com
Der Vorteil, den ich sehe, ist die Vermeidung von Duplikaten der $ uri / images in einem bestimmten Beispiel, wenn Alias ​​verwendet wird
antonbormotov
21

Nur eine kurze Ergänzung zu der sehr hilfreichen Antwort von @ good_computer. Ich wollte das Stammverzeichnis der URL durch einen Ordner ersetzen, aber nur, wenn es mit einem Unterordner übereinstimmt, der statische Dateien enthält (die ich als Teil des Pfads beibehalten wollte).

Wenn sich beispielsweise die angeforderte Datei in /app/jsoder befindet /app/css, suchen Sie in /app/location/public/[that folder].

Ich habe das mit einem Regex zum Laufen gebracht.

 location ~ ^/app/((images/|stylesheets/|javascripts/).*)$ {
     alias /home/user/sites/app/public/$1;
     access_log off;
     expires max;
 }
Meloncholie
quelle
2
Danke für diese Antwort. Ich weiß, dass dies 3 Jahre später ist, aber könnte jemand erklären, ob es einen Kompromiss zwischen Leistung und / oder Sicherheit zwischen der Verwendung von Alias ​​und Root gibt?
Mina
1
@Mina Es ist besser, root zu verwenden, wenn du kannst. (Es gibt einen Kommentar in der Dokumentation wiki.nginx.org/HttpCoreModule#alias )
Matthew Wilcoxson
Dies ist genau das, was ich hierher gekommen
bin
6

aliaswird verwendet, um den Location Part Path (LPP) im Anforderungspfad zu ersetzen, während der rootdem Anforderungspfad vorangestellt wird.

Es gibt zwei Möglichkeiten, den Anforderungspfad dem endgültigen Dateipfad zuzuordnen.

aliaskann nur im Standortblock verwendet werden und überschreibt die Außenseite root.

aliasund rootkann nicht zusammen im Standortblock verwendet werden.

Yao Zhao
quelle
3
server {
    server_name xyz.com;
    root /home/ubuntu/project_folder/;

    client_max_body_size 10M;
    access_log  /var/log/nginx/project.access.log;
    error_log  /var/log/nginx/project.error.log;

    location /static {
        index index.html;
    }

    location /media {
        alias /home/ubuntu/project/media/;
    }
}

Server blockieren, um die statische Seite auf Nginx zu leben.

Tapish
quelle
2

Mit anderen Worten, wenn Sie sich kurz fassen: Im Falle von rootist das angegebene Standortargument Teil des Pfads und der URI des Dateisystems . Auf der anderen Seite - für aliasDirektiven ist das Argument der Standortanweisung nur Teil des URI

Es handelt sich also aliasum einen anderen Namen, der einen bestimmten URI einem bestimmten Pfad im Dateisystem rootzuordnet , während das Standortargument an den Stammpfad angehängt wird, der als Argument für die rootDirektive angegeben wird.

Twissell
quelle