Nginx - kebingungan penyajian file statis dengan root & alias

473

Saya perlu melayani aplikasi saya melalui server aplikasi saya di 8080, dan file statis saya dari direktori tanpa menyentuh server aplikasi. Konfigurasi nginx yang saya miliki adalah sesuatu seperti ini ...

    # 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;
            }
    }

Sekarang, dengan konfigurasi ini, semuanya berfungsi dengan baik. Perhatikan bahwa rootarahan dikomentari.

Jika saya mengaktifkan rootdan menonaktifkan alias- itu berhenti berfungsi. Namun, ketika saya menghapus trailing /static/dari rootitu mulai berfungsi lagi.

Dapatkah seseorang menjelaskan apa yang terjadi. Juga tolong jelaskan dengan jelas dan lisan apa perbedaan antara rootdan alias, dan tujuan mereka.

treecoder
sumber

Jawaban:

1074

Saya telah menemukan jawaban atas kebingungan saya.

Ada perbedaan yang sangat penting antara rootdan aliasarahan. Perbedaan ini ada dalam cara jalur yang ditentukan dalam rootatau aliasdiproses.

Dalam hal rootarahan, path lengkap ditambahkan ke root termasuk bagian lokasi , sedangkan dalam hal aliasarahan, hanya bagian dari path TIDAK termasuk bagian lokasi ditambahkan ke alias .

Menggambarkan:

Katakanlah kita memiliki konfigurasi

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

Dalam hal ini jalan akhir yang akan diperoleh Nginx adalah

/var/www/app/static/static

Ini akan kembali 404karena tidak ada di static/dalamstatic/

Ini karena bagian lokasi ditambahkan ke jalur yang ditentukan dalam root. Karenanya, dengan root, cara yang benar adalah

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

Di sisi lain, dengan alias, bagian lokasi akan jatuh . Jadi untuk konfigurasi

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

jalan terakhir akan dengan benar dibentuk sebagai

/var/www/app/static

Kasus trailing slash untuk aliasdirektif

Tidak ada pedoman yang pasti tentang apakah garis miring adalah wajib menurut dokumentasi Nginx , tetapi pengamatan umum oleh orang-orang di sini dan di tempat lain tampaknya menunjukkan hal itu.

Beberapa tempat lagi telah membahas hal ini, meskipun tidak meyakinkan.

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

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

treecoder
sumber
97
Garis miring di jalur alias sangat penting!
mafrosis
2
Ini semua hebat (ini membantu saya memperbaiki masalah konfigurasi saya), tapi saya ingin tahu pengaturan logging apa yang dapat digunakan orang untuk membantu mendiagnosis masalah seperti ini? Seperti, apa pun yang akan dicetak ke log hal-hal seperti "permintaan yang diterima untuk [...], dicocokkan dengan" lokasi [...] "blok konfigurasi, direktori pencarian [...]"
Pistos
2
@Pistos: dimasukkan log_format scripts '$document_root | $uri | > $request';ke dalam httpbagian dan access_log /var/log/nginx/scripts.log scripts;ke dalam serverbagian konfigurasi nginx ..
helvete
Terima kasih! Memang trailing slash sangat penting di alias, kalau tidak saya dapatkan nginx: [emerg] invalid number of arguments in "alias" directive, dan server turun selama restart.
FotisK
@ mafrosis Mengapa ini penting?
Bruce Sun
104

sebagai katakan sebagai @treecoder

Dalam hal rootarahan, path lengkap ditambahkan ke root termasuk bagian lokasi, sedangkan dalam kasus aliasarahan, hanya bagian dari path TIDAK termasuk bagian lokasi ditambahkan ke alias.

Sebuah gambar bernilai ribuan kata

untuk root:

masukkan deskripsi gambar di sini

untuk alias:

masukkan deskripsi gambar di sini

liuzhijun
sumber
11
Haruskah panah pertama pada gambar kedua menjadi "+"?
aioobe
35

Dalam kasus Anda, Anda dapat menggunakan rootarahan, karena $uribagian dari locationarahan itu sama dengan rootbagian arahan terakhir .

Dokumentasi Nginx juga menyarankannya:
Ketika lokasi cocok dengan bagian terakhir dari nilai direktif:

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

lebih baik menggunakan direktif root sebagai gantinya:

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

dan rootarahan akan ditambahkan $urike jalan.

antonbormotov
sumber
2
Mengapa ini lebih baik? Documents juga tidak mengatakan.
HostedMetrics.com
Manfaat yang saya lihat adalah untuk menghindari duplikasi $ uri, / gambar dalam contoh yang diberikan, ketika menggunakan alias
antonbormotov
21

Hanya tambahan cepat ke jawaban @ good_computer yang sangat membantu, saya ingin mengganti ke root dari URL dengan folder, tetapi hanya jika itu cocok dengan subfolder yang berisi file statis (yang ingin saya pertahankan sebagai bagian dari path).

Misalnya jika file yang diminta ada di /app/jsatau /app/css, lihat /app/location/public/[that folder].

Saya mendapatkan ini untuk bekerja menggunakan regex.

 location ~ ^/app/((images/|stylesheets/|javascripts/).*)$ {
     alias /home/user/sites/app/public/$1;
     access_log off;
     expires max;
 }
meloncholy
sumber
2
Terima kasih atas jawaban ini. Saya tahu ini 3 tahun kemudian, tetapi adakah yang bisa menjelaskan apakah ada kinerja dan / atau pertukaran keamanan antara menggunakan alias versus root?
Mina
1
@Mina Lebih baik menggunakan root jika Anda bisa. (Ada komentar di dokumen wiki.nginx.org/HttpCoreModule#alias )
Matthew Wilcoxson
Inilah yang saya datang ke sini untuk 👍👏
alienfromouterspace
6

aliasdigunakan untuk mengganti path bagian lokasi (LPP) di jalur permintaan, sementara rootdigunakan untuk ditambahkan ke jalur permintaan.

Mereka adalah dua cara untuk memetakan jalur permintaan ke jalur file akhir.

aliashanya dapat digunakan di blok lokasi, dan itu akan menggantikan bagian luar root.

aliasdan roottidak dapat digunakan dalam blok lokasi bersama.

Yao Zhao
sumber
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/;
    }
}

Blok server untuk menjalankan halaman statis di nginx.

Tapish
sumber
2

Dengan kata lain tentang menjaga singkat ini: dalam kasus root, argumen lokasi yang ditentukan adalah bagian dari jalur filesystem dan URI . Di sisi lain - untuk aliasargumen direktif pernyataan lokasi adalah bagian dari URI saja

Jadi, aliasadalah nama yang berbeda yang memetakan URI tertentu ke jalur tertentu di sistem file, sedangkan rootmenambahkan argumen lokasi ke jalur root yang diberikan sebagai argumen untuk rootdirektif.

Twissell
sumber