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

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

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

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

我遇到的最大问题之一是,我很想使用命名位置来对一组会议进行分组,例如。

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

但这是好办法吗?对于非常通用的设置(例如代理设置),这听起来还不错,但必须打开不同的文件才能获得完整的配置,这样可读性就很差了。

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

问题

是否存在“官方”最佳实践来编写好的、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 配置 DRY 起来?

答案1

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

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

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

答案2

有没有办法直接“调用”命名位置?!

至少还有一种方法:

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

答案3

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

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

答案4

有没有办法直接“调用”命名位置?!==> 这很简单

尝试文件/dev/null@test;

相关内容