如何编写具有命名位置的 DRY、模块化 nginx conf(反向代理)

Ste*_*ano 26 configuration nginx

我主要使用 nginx 作为几个 gunicon/mod_wsgi 应用程序前面的反向缓存代理,当然还有服务器静态文件。

我发现很快我的 nginx 配置就变得无法维护;问题是我有一些相似(甚至相同)的模式,但我无法使它干净。

我遇到的最大问题之一是我喜欢使用命名位置作为对一组 conf 进行分组的一种方式,例如。

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;
}
Run Code Online (Sandbox Code Playgroud)

注意。 问题在于同时拥有 gunicorn 和 wsgi。那只是一个例子。另一种是:

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
}
Run Code Online (Sandbox Code Playgroud)

但是要调用命名位置,我发现的唯一方法是:

location /somelocation {
    try_files $uri @named_location;
}
Run Code Online (Sandbox Code Playgroud)

这已经感觉不对,我希望nginx的去看看静态文件,我希望它直接进入指定的位置!有没有办法直接“调用”命名位置?!

我认为我可以干的另一种方式是很多include......

location /somelocation {
    include django_unicorn.conf;
}
Run Code Online (Sandbox Code Playgroud)

但这是一个好方法吗?对于非常通用的设置(例如代理设置)来说,这听起来不错,但是必须打开不同的文件才能获得完整的配置文件并不是很容易阅读。

此外,在某些情况下,我可以使用正则表达式将几个位置分组,但我只喜欢在它们逻辑相关时才这样做,而不仅仅是为了能够将通用设置放在同一块中。

问题

是否有编写好的 DRY nginx 配置的“官方”最佳实践?

我很想找到一个模式,如:

location / {
    common confs
    try_files $uri @name_location
}
Run Code Online (Sandbox Code Playgroud)

** 但是我如何为不同的位置编写特定的案例?**

我可以简单地添加几个位置,其中包含 conf 的不常见部分和 @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
}
Run Code Online (Sandbox Code Playgroud)

当我有不同的 url 指向相同的资源时,我可以简单地进行重写吗?

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
}
Run Code Online (Sandbox Code Playgroud)

还是应该将它们全部归为一个位置?

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
}
Run Code Online (Sandbox Code Playgroud)

有关的

我在邮件列表中找不到太多内容,在 wiki 中更是如此。

请注意,这与问题NGinx 最佳实践/ 不 / 相同- 这是一个非常通用的问题。

另一个更相关:我如何干掉这个 Nginx 配置?

Duk*_*ion 6

我已经使用 nginx 地图功能解决了类似的问题。

首先创建一个域名到后端映射:

map $http_host $backend {
  myhost1.tld 192.168.1.100;
  myhost2.tld 192.168.1.101;
  default     upstream_pool1;
}
Run Code Online (Sandbox Code Playgroud)

然后在位置使用地图

location / {
  common settings
  proxy_pass $backend; 
}
Run Code Online (Sandbox Code Playgroud)

您可以使用任何其他变量代替 $http_host 请参阅本手册:http ://nginx.org/en/docs/http/ngx_http_map_module.html