Cách viết DRY, mô đun nginx conf (proxy ngược) với các vị trí được đặt tên


25

Tôi đang sử dụng nginx chủ yếu như một proxy lưu trữ ngược lại trước một số ứng dụng gunicon / mod_wsgi và tất nhiên là cho các tệp tĩnh của máy chủ.

Tôi thấy rằng nhanh chóng confs nginx của tôi trở nên không thể duy trì; vấn đề là tôi có một vài mẫu tương tự (hoặc thậm chí giống hệt nhau) nhưng tôi không thể quản lý để làm cho nó sạch.

Một trong những vấn đề lớn nhất mà tôi có là tôi rất thích sử dụng các vị trí được đặt tên như một cách để nhóm một nhóm confs, ví dụ.

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

Lưu ý Vấn đề là không có cả gunicorn và wsgi. Đó chỉ là một ví dụ. Một số khác là:

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
}

nhưng để gọi một vị trí được đặt tên theo cách duy nhất tôi tìm thấy là:

location /somelocation {
    try_files $uri @named_location;
}

Điều này đã không cảm thấy đúng, tôi không muốn nginx đi tìm các tệp tĩnh, tôi muốn nó đi trực tiếp đến vị trí được đặt tên! Có cách nào để "gọi" một vị trí được đặt tên trực tiếp không?!

Một cách khác tôi nghĩ rằng tôi có thể đi khô là rất nhiều include...

location /somelocation {
    include django_unicorn.conf;
}

Nhưng đây có phải là một cách tốt để làm điều đó? Nghe có vẻ ổn đối với các cài đặt rất chung chung (ví dụ: các proxy), nhưng không thể đọc được các tệp khác nhau để có được thông tin đầy đủ.

Ngoài ra, trong một số trường hợp, tôi có thể nhóm một vài vị trí với biểu thức chính quy, nhưng tôi thích làm CHỈ khi chúng có liên quan về mặt logic không chỉ để có thể đặt các cài đặt chung trong cùng một khối.

Câu hỏi

Có một thực hành tốt nhất "chính thức" để viết cấu hình nginx tốt, DRY không?

Tôi rất thích tìm một mô hình như:

location / {
    common confs
    try_files $uri @name_location
}

** nhưng làm cách nào để viết trường hợp cụ thể cho các vị trí khác nhau? **

Tôi có thể chỉ cần thêm một số vị trí với phần không phổ biến của conf và vị trí phổ biến trong @named_location không?

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
}

Khi tôi có các url khác nhau trỏ đến cùng một tài nguyên, tôi có thể viết lại không?

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
}

hoặc những người nên được nhóm vào một địa điểm?

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
}

Liên quan

Tôi không thể tìm thấy nhiều trong danh sách gửi thư, thậm chí còn ít hơn trong wiki.

Xin lưu ý đây là / không / giống như câu hỏi Thực tiễn tốt nhất NGinx - đó là một câu hỏi rất chung chung.

Một cái khác có liên quan hơn: Làm cách nào để DRY cấu hình Nginx này?

Câu trả lời:


6

Tôi đã giải quyết vấn đề tương tự bằng tính năng nginx map.

Đầu tiên tạo một tên miền cho bản đồ phụ trợ:

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

sau đó sử dụng bản đồ ở vị trí

location / {
  common settings
  proxy_pass $backend; 
}

Bạn có thể sử dụng bất kỳ biến nào khác thay vì $ http_host Xem hướng dẫn này: http://nginx.org/en/docs/http/ngx_http_map_module.html


Tôi không biết về map- hoặc ít nhất là tôi chưa bao giờ nhận thấy và nghĩ rằng tôi có thể sử dụng nó như thế này ... hãy để tôi suy nghĩ thêm một chút về điều này và xem nếu tôi có thêm câu hỏi / nhận xét!
Stefano

2

Có cách nào để "gọi" một vị trí được đặt tên trực tiếp không?!

Có ít nhất một cách nữa:

location /somelocation {
    error_page 418 = @named_location;
    return 418;
}

Đã tìm thấy hack này khiến nginx quên, ví dụ: "proxy_read_timeout" được đặt bên trong "/ somelocation" khi nginx "return" -s thành "@named_location".
Denis Ryzhkov

1
Tôi thực sự là một ấm trà ?
Walf

0

Một số chỉ thị có thể được áp dụng cho cả bối cảnh "máy chủ" và "vị trí", làm cho nó KHÔ:

# 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;
}
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.