Cara menulis KERING, modular nginx conf (proxy terbalik) dengan lokasi yang ditentukan

25

Saya menggunakan nginx sebagian besar sebagai reverse cachining proxy di depan beberapa aplikasi gunicon / mod_wsgi dan tentu saja ke server file statis.

Saya menemukan bahwa dengan cepat nginx confs saya menjadi tidak mungkin untuk dipertahankan; masalahnya adalah saya memiliki beberapa pola yang serupa (atau bahkan identik) tetapi saya tidak dapat membuatnya bersih.

Salah satu masalah terbesar yang saya miliki adalah bahwa saya akan senang menggunakan lokasi yang disebutkan sebagai cara untuk mengelompokkan satu set conf, misalnya.

location @django_modwsgi {
    include proxy.conf;
    proxy_pass  http://127.0.0.1:8080;        
}

location @django_gunicorn {
    include proxy.conf; # this could also be included directly in the server {} block?
    proxy_pass  http://gunicorn_builder;
}

NB. Masalahnya adalah tidak memiliki gunicorn dan wsgi. Itu hanya sebuah contoh. Yang lain adalah:

location @namedlocation_1 {
     some cache settings;
     some cache_key settings;
     ignore some headers;
     expires;
     proxy_pass
}

location @namedlocation_2 {
     other cache settings;
     other cache_key settings;
     ignore some headers;
     expires;
     proxy_pass
}

tetapi untuk memanggil lokasi yang disebutkan satu-satunya cara saya temukan adalah:

location /somelocation {
    try_files $uri @named_location;
}

Ini sudah terasa tidak benar, saya tidak ingin nginx mencari file statis, saya ingin langsung ke lokasi yang ditentukan! Apakah ada cara untuk "memanggil" lokasi yang disebutkan secara langsung ?!

Cara lain saya pikir saya bisa kering adalah banyak include...

location /somelocation {
    include django_unicorn.conf;
}

Tetapi apakah ini cara yang baik untuk melakukannya? Kedengarannya ok untuk pengaturan yang sangat umum (mis. Yang proxy), tetapi tidak terlalu mudah dibaca harus membuka file yang berbeda untuk mendapatkan conf penuh.

Juga, dalam beberapa kasus saya dapat mengelompokkan beberapa lokasi dengan regexp, tetapi saya suka HANYA ketika mereka terkait secara logis tidak hanya untuk dapat menempatkan pengaturan umum di blok yang sama.

Pertanyaan

Apakah ada praktik terbaik "resmi" untuk menulis konfigurasi nginx yang bagus dan KERING?

Saya akan senang menemukan pola seperti:

location / {
    common confs
    try_files $uri @name_location
}

** tetapi bagaimana saya menulis kasus khusus untuk lokasi yang berbeda? **

Bisakah saya menambahkan beberapa lokasi dengan bagian yang tidak umum dari conf dan yang umum di @named_location?

location /1/ {
    some cache expire settings;
    NOTHING ELSE;
}

location /2/ {
    some other cache expire settings;
    NOTHING ELSE;
}

location / {
    common settings
    try_files
}

location @named_location {
    other common settings for this named location only
    proxy_pass
}

Ketika saya memiliki url berbeda yang menunjuk ke sumber yang sama, bisakah saya menulis ulang?

location /1/ {
    rewrite  ^  /3/  last;
}

location /2/ {
    rewrite ^   /4/  last; 
}

location / {
    common settings
    try_files
}

location @named_location {
    other common settings for this named location only
    proxy_pass
}

atau haruskah mereka semua dikelompokkan ke dalam satu lokasi?

location / {
    rewrite ^/1/$  /3/  last;
    rewrite ^/2/$   /4/  last; 

    common settings
    try_files
}

location @named_location {
    other common settings for this named location only
    proxy_pass
}

Terkait

Saya tidak dapat menemukan banyak di milis, apalagi di wiki.

Harap perhatikan ini / tidak / sama dengan pertanyaan NGinx Best Practices - itu pertanyaan yang sangat umum.

Yang lain ini lebih relevan: Bagaimana cara KERING konfigurasi Nginx ini?

Stefano
sumber

Jawaban:

6

Saya telah memecahkan masalah yang sama menggunakan fitur peta nginx.

Pertama-tama buat nama domain ke backend peta:

map $http_host $backend {
  myhost1.tld 192.168.1.100;
  myhost2.tld 192.168.1.101;
  default     upstream_pool1;
}

kemudian gunakan peta di lokasi

location / {
  common settings
  proxy_pass $backend; 
}

Anda dapat menggunakan variabel lain alih-alih $ http_host. Lihat panduan ini: http://nginx.org/en/docs/http/ngx_http_map_module.html

DukeLion
sumber
Saya tidak tahu map- atau setidaknya saya tidak pernah memperhatikan dan berpikir saya bisa menggunakannya seperti ini ... izinkan saya merenungkan sedikit lebih banyak tentang ini dan melihat apakah saya memiliki pertanyaan / komentar tambahan!
Stefano
2

Apakah ada cara untuk "memanggil" lokasi yang disebutkan secara langsung ?!

Setidaknya ada satu cara lagi:

location /somelocation {
    error_page 418 = @named_location;
    return 418;
}
MingalevME
sumber
Menemukan peretasan ini membuat nginx melupakan mis. "Proxy_read_timeout" set inside "/ somelocation" ketika nginx "return" -s ke "@named_location".
Denis Ryzhkov
1
418 Saya seorang teko Benarkah?
Walf
0

Beberapa arahan dapat diterapkan untuk konteks "server" dan "lokasi", menjadikannya KERING:

# The variables below are evaluated on each request,
# allowing to DRY configs of locations.
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $connection_upgrade;
proxy_set_header X-Real-IP $remote_addr;

location /special {
    proxy_send_timeout 10m;
    proxy_read_timeout 10m;
    proxy_pass http://pool;
}

location / {
    proxy_pass http://pool;
}
Denis Ryzhkov
sumber