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


25

我主要将nginx用作几个gunicon / mod_wsgi应用程序前面的逆向代理,当然还用于服务器静态文件。

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

我遇到的最大问题之一是,我很想使用命名位置作为对一组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;
}

注意 问题在于同时拥有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
}

但是打电话给命名位置的唯一途径是:

location /somelocation {
    try_files $uri @named_location;
}

这已经感觉不对,我希望nginx的去看看静态文件,我希望它直接进入指定的位置!有没有一种方法可以直接“呼叫”命名位置?

我认为我可以干的另一种方法是include...

location /somelocation {
    include django_unicorn.conf;
}

但这是一个好方法吗?对于非常通用的设置(例如,代理设置)来说,这听起来还可以,但是必须打开不同的文件以获取完整的conf并不是很容易理解。

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

问题

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

我很想找到一个像这样的模式:

location / {
    common confs
    try_files $uri @name_location
}

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

我可以简单地在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
}

当我有指向相同资源的不同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
}

还是应该将所有这些分组到一个位置?

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
}

有关

我在邮件列表中找不到很多,甚至在Wiki中也找不到。

请注意,这与NGinx最佳做法问题相同/不相同-这是一个非常笼统的问题。

另一个更相关:如何干燥此Nginx配置?

Answers:


6

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

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

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

然后在位置使用地图

location / {
  common settings
  proxy_pass $backend; 
}

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


我不知道map-或至少我从未注意到并认为我可以像这样使用它...让我仔细考虑一下,看看是否还有其他问题/意见!
斯特凡诺

2

有没有一种方法可以直接“呼叫”命名位置?

至少还有一种方法:

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

发现此hack使nginx忘记了当nginx“返回” -s到“ @named_location”时在“ / somelocation”中设置的“ proxy_read_timeout”。
Denis Ryzhkov

1
第418章我是茶壶吗?
沃尔夫,

0

某些指令可以同时应用于“服务器”和“位置”上下文,从而使其变干:

# 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;
}
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.