基于位置的动态 proxy_pass
Dynamic proxy_pass based on location
我正在尝试根据位置创建动态 proxy_pass(在 docker 中成为 运行,并将流量重定向到托管 http 的 docker 堆栈,基于堆栈姓名)
这是我当前的配置。我已经到了使用静态位置进行重定向的地步(底部的评论变体 blue/green 正确重定向并且应用程序运行正常)。我在动态位置 (~^/(?<ver>.*)/(?<rest>.*)?$)
方面遇到问题 - 目标 URL 的正确粘合存在问题。当我转到 https://myapp.com/blue/
时,nginx 记录了 dns 解析 blue could not be resolved (3: Host not found)
的问题,看起来它在 http://${ver}_${subdomain}/$rest
中的 $<ver>
之后削减了所有内容。我不是 REGEX 专家,我可能搞砸了 location
部分,有什么建议吗?
server {
listen 80;
server_name ~^(?<subdomain>.+)\.(mydomain\.com|mydomain\.pl)$;
resolver 127.0.0.11 ipv6=off;
location ~^/(?<ver>.*)/(?<rest>.*)?$ {
set $target http://${ver}_${subdomain}/$rest;
proxy_pass $target;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
# location ~ ^/blue/((?<rest>.*))?$ {
# set $exdomain http://blue_$subdomain/$rest;
# proxy_pass $exdomain;
# proxy_set_header Host $host;
# proxy_set_header X-Real-IP $remote_addr;
# proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
# }
# location ~ ^/green/((?<rest>.*))?$ {
# set $exdomain http://green_$subdomain/$rest;
# proxy_pass $exdomain;
# proxy_set_header Host $host;
# proxy_set_header X-Real-IP $remote_addr;
# proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
# }
proxy_connect_timeout 90;
proxy_send_timeout 90;
proxy_read_timeout 90;
send_timeout 90;
}
*
在正则表达式中是贪心的,因此 $ver
将捕获所有内容,直到 last /
,而不是下一个 /
如你所愿。
一种解决方案是使用 non-greedy 变体 *?
(不要与 ?
混淆),例如:
location ~ ^/(?<ver>.*?)/(?<rest>.*)?$ { ... }
但更好的解决方案是使用排除/
的字符class,例如:
location ~ ^/(?<ver>[^/]+)/(?<rest>.*)?$ { ... }
参见 this useful resource 正则表达式。
我正在尝试根据位置创建动态 proxy_pass(在 docker 中成为 运行,并将流量重定向到托管 http 的 docker 堆栈,基于堆栈姓名)
这是我当前的配置。我已经到了使用静态位置进行重定向的地步(底部的评论变体 blue/green 正确重定向并且应用程序运行正常)。我在动态位置 (~^/(?<ver>.*)/(?<rest>.*)?$)
方面遇到问题 - 目标 URL 的正确粘合存在问题。当我转到 https://myapp.com/blue/
时,nginx 记录了 dns 解析 blue could not be resolved (3: Host not found)
的问题,看起来它在 http://${ver}_${subdomain}/$rest
中的 $<ver>
之后削减了所有内容。我不是 REGEX 专家,我可能搞砸了 location
部分,有什么建议吗?
server {
listen 80;
server_name ~^(?<subdomain>.+)\.(mydomain\.com|mydomain\.pl)$;
resolver 127.0.0.11 ipv6=off;
location ~^/(?<ver>.*)/(?<rest>.*)?$ {
set $target http://${ver}_${subdomain}/$rest;
proxy_pass $target;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
# location ~ ^/blue/((?<rest>.*))?$ {
# set $exdomain http://blue_$subdomain/$rest;
# proxy_pass $exdomain;
# proxy_set_header Host $host;
# proxy_set_header X-Real-IP $remote_addr;
# proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
# }
# location ~ ^/green/((?<rest>.*))?$ {
# set $exdomain http://green_$subdomain/$rest;
# proxy_pass $exdomain;
# proxy_set_header Host $host;
# proxy_set_header X-Real-IP $remote_addr;
# proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
# }
proxy_connect_timeout 90;
proxy_send_timeout 90;
proxy_read_timeout 90;
send_timeout 90;
}
*
在正则表达式中是贪心的,因此 $ver
将捕获所有内容,直到 last /
,而不是下一个 /
如你所愿。
一种解决方案是使用 non-greedy 变体 *?
(不要与 ?
混淆),例如:
location ~ ^/(?<ver>.*?)/(?<rest>.*)?$ { ... }
但更好的解决方案是使用排除/
的字符class,例如:
location ~ ^/(?<ver>[^/]+)/(?<rest>.*)?$ { ... }
参见 this useful resource 正则表达式。