nginx 根据主机名中的索引反向代理到不同的应用程序
nginx reverse proxy to different applications based on an index in the host name
以前,我有一个可在 DNS staging.example.com/
后面访问的暂存环境。这个地址后面是一个 nginx 代理,配置如下。请注意,我的代理要么重定向
- 到一个(s3 后面)cloudfront 分布 (app1)
- 通过转发主机名到负载均衡器(假设我的 ALB 能够根据主机名选择合适的应用程序)(app2)
server {
listen 80;
listen 443 ssl;
server_name
staging.example.com
;
location / {
try_files /maintenance.html @app1;
}
location ~ /(faq|about_us|terms|press|...) {
try_files /maintenance.html @app2;
}
[...] # Lots of similar config than redirects either to app1 or app2
# Application hosted on s3 + CloudFront
location @app1 {
proxy_set_header Host app1-staging.example.com;
proxy_pass http://d2c72vkj8qy1kv.cloudfront.net;
}
# Application hosted behind a load balancer
location @app2 {
proxy_set_header Host app2-staging.example.internal;
proxy_set_header X-ALB-Host $http_host;
proxy_pass https://staging.example.internal;
}
}
现在,我的团队需要更多的暂存环境。我们还没有准备好过渡到 docker 部署(最终目标是能够为我们需要测试的每个分支生成一个完整的基础设施……考虑到我们的团队规模,这有点过分了),我正在尝试取而代之的是一些技巧,这样我们就可以轻松地获得更多的暂存环境使用大致相同的 nginx 配置。
假设我已经创建了一些带有 index_i
的 DNS 名称,例如 staging1.example.com
、staging2.example.com
。所以我的 nginx 代理将接收主机 header 看起来像 staging#{index_i}.example.com
的请求
我在想做什么:
- 对于我的 s3 + Cloudfront 应用程序,我正在考虑将我的文件嵌套在
[bucket_id]/#{index_i}/[app1_files]
下(之前它们直接位于根文件夹 [bucket_id]/[app1_files]
中)
- 对于我的负载均衡器应用程序,假设我的负载均衡器知道在哪里分派
https://staging#{iindex_i}.example.com
个请求。
我正在尝试拉出这样的东西
# incoming host : staging{index_i}.example.com`
server {
listen 80;
listen 443 ssl;
server_name
staging.example.com
staging1.example.com
staging2.example.com # I can list them manually, but is it possible to have something like `staging*.example.com` ?
;
[...]
location @app1 {
proxy_set_header Host app1-staging$index_i.example.com; # Note the extra index_i here
proxy_pass http://d2c72vkj8qy1kv.cloudfront.net/$index_i; # Here proxy_passing to a subfolder named index_i
}
location @app2 {
proxy_set_header Host app2-staging$index_i.example.internal; # Note the extra index_i here
proxy_set_header X-ALB-Host $http_host;
proxy_pass http://staging$index_i.example.internal; # Here I am just forwarding the host header basically
}
所以最终我的问题是
- 当我的 nginx 服务器接收到连接时,我可以从请求主机 header 中提取 index_i
变量(可能使用一些正则表达式吗?)
- 如果是,如何使用 index_i
有效地实现 app1 和 app2 块?
在查看了其他几个问题后,我得出了这个完美运行的配置:可以在主机名中使用正则表达式来提取所述变量。
不利的一面是,对于我的静态单页应用程序,要使其与 S3 一起使用,我必须为每个 "staging index" 创建一个存储桶(因为 S3 上的静态托管与网站托管/a单个 index.html 用于 404)。这反过来又使我无法在我的(以前是单一的)s3 之前使用单一的 Cloudfront 发行版。
这是在 ALB 后面使用带有 create-react-app 前端和服务器端呈现的代理的示例
server {
listen 80;
listen 443 ssl;
server_name ~^staging(?<staging_index>\d*).myjobglasses.com$
location @create-react-app-frontend {
proxy_pass http://staging$staging_index.example.com.s3-website.eu-central-1.amazonaws.com;
}
location @server-side-rendering-app {
# Now Amazon Application Load Balancer can redirect traffic based on ANY HTTP header
proxy_set_header EXAMPLE-APP old-frontend;
proxy_pass https://staging$staging_index.myjobglasses.com;
}
以前,我有一个可在 DNS staging.example.com/
后面访问的暂存环境。这个地址后面是一个 nginx 代理,配置如下。请注意,我的代理要么重定向
- 到一个(s3 后面)cloudfront 分布 (app1)
- 通过转发主机名到负载均衡器(假设我的 ALB 能够根据主机名选择合适的应用程序)(app2)
server {
listen 80;
listen 443 ssl;
server_name
staging.example.com
;
location / {
try_files /maintenance.html @app1;
}
location ~ /(faq|about_us|terms|press|...) {
try_files /maintenance.html @app2;
}
[...] # Lots of similar config than redirects either to app1 or app2
# Application hosted on s3 + CloudFront
location @app1 {
proxy_set_header Host app1-staging.example.com;
proxy_pass http://d2c72vkj8qy1kv.cloudfront.net;
}
# Application hosted behind a load balancer
location @app2 {
proxy_set_header Host app2-staging.example.internal;
proxy_set_header X-ALB-Host $http_host;
proxy_pass https://staging.example.internal;
}
}
现在,我的团队需要更多的暂存环境。我们还没有准备好过渡到 docker 部署(最终目标是能够为我们需要测试的每个分支生成一个完整的基础设施……考虑到我们的团队规模,这有点过分了),我正在尝试取而代之的是一些技巧,这样我们就可以轻松地获得更多的暂存环境使用大致相同的 nginx 配置。
假设我已经创建了一些带有 index_i
的 DNS 名称,例如 staging1.example.com
、staging2.example.com
。所以我的 nginx 代理将接收主机 header 看起来像 staging#{index_i}.example.com
我在想做什么:
- 对于我的 s3 + Cloudfront 应用程序,我正在考虑将我的文件嵌套在
[bucket_id]/#{index_i}/[app1_files]
下(之前它们直接位于根文件夹[bucket_id]/[app1_files]
中) - 对于我的负载均衡器应用程序,假设我的负载均衡器知道在哪里分派
https://staging#{iindex_i}.example.com
个请求。
我正在尝试拉出这样的东西
# incoming host : staging{index_i}.example.com`
server {
listen 80;
listen 443 ssl;
server_name
staging.example.com
staging1.example.com
staging2.example.com # I can list them manually, but is it possible to have something like `staging*.example.com` ?
;
[...]
location @app1 {
proxy_set_header Host app1-staging$index_i.example.com; # Note the extra index_i here
proxy_pass http://d2c72vkj8qy1kv.cloudfront.net/$index_i; # Here proxy_passing to a subfolder named index_i
}
location @app2 {
proxy_set_header Host app2-staging$index_i.example.internal; # Note the extra index_i here
proxy_set_header X-ALB-Host $http_host;
proxy_pass http://staging$index_i.example.internal; # Here I am just forwarding the host header basically
}
所以最终我的问题是
- 当我的 nginx 服务器接收到连接时,我可以从请求主机 header 中提取 index_i
变量(可能使用一些正则表达式吗?)
- 如果是,如何使用 index_i
有效地实现 app1 和 app2 块?
在查看了其他几个问题后,我得出了这个完美运行的配置:可以在主机名中使用正则表达式来提取所述变量。
不利的一面是,对于我的静态单页应用程序,要使其与 S3 一起使用,我必须为每个 "staging index" 创建一个存储桶(因为 S3 上的静态托管与网站托管/a单个 index.html 用于 404)。这反过来又使我无法在我的(以前是单一的)s3 之前使用单一的 Cloudfront 发行版。
这是在 ALB 后面使用带有 create-react-app 前端和服务器端呈现的代理的示例
server {
listen 80;
listen 443 ssl;
server_name ~^staging(?<staging_index>\d*).myjobglasses.com$
location @create-react-app-frontend {
proxy_pass http://staging$staging_index.example.com.s3-website.eu-central-1.amazonaws.com;
}
location @server-side-rendering-app {
# Now Amazon Application Load Balancer can redirect traffic based on ANY HTTP header
proxy_set_header EXAMPLE-APP old-frontend;
proxy_pass https://staging$staging_index.myjobglasses.com;
}