【问题标题】:Serving different static folders per location with nginx使用 nginx 为每个位置提供不同的静态文件夹
【发布时间】:2021-01-30 20:21:31
【问题描述】:

TL;DR

我需要为托管在同一台机器上但位于两个非常不同的路径的两个容器化应用程序(每个应用程序位于不同的端口)提供服务,并使用 nginx 反向代理使用它们自己的静态子文件夹。

上下文

我经历了很多 Q/A,其中包含一些额外复杂的内容,这些内容对我理解如何使用nginx 为每个位置提供一些静态文件夹的本质没有太大帮助。每个位置

让我通过简单而整洁的起始反向代理配置来解释“每个位置”的含义:

server {
    listen 80;
    listen [::]:80;

    root /var/www;
    server_name my.server.org;

    access_log /var/log/nginx/access.log;
    error_log /var/log/nginx/error.log;

    location /app-a {
        proxy_pass http://127.0.0.1:8080/;
    }

    location /app-b {
        proxy_pass http://127.0.0.1:8081/;
    }
}

这很好用,只是不提供静态文件(css、js、...)。

因此,我将其更改如下以检索app-b 的这些文件:

server {
    listen 80;
    listen [::]:80;

    root /var/www;
    server_name my.server.org;

    access_log /var/log/nginx/access.log;
    error_log /var/log/nginx/error.log;

    location /app-a {
        proxy_pass http://127.0.0.1:8080/;
    }

    location /app-b {
        proxy_pass http://127.0.0.1:8081/;
    }
    location ^~ /static/ {
        include /etc/nginx/mime.types;
        root /home/debian/projects/crystallography/web/app-b/;
    }
}

而且效果更好;我现在拥有app-b 的这些静态文件。但是app-a 当然仍然没有。

现在,您明白我的意思了...我还需要为 app-a 自己的静态文件夹提供服务。


我测试过的内容

这是我尝试过的两个主要想法(但都不起作用)+其他变体(也不起作用):

  1. 添加额外的静态位置(似乎先验是一种干净的方式)
server {
    listen 80;
    listen [::]:80;

    root /var/www;
    server_name my.server.org;

    access_log /var/log/nginx/access.log;
    error_log /var/log/nginx/error.log;

    location /app-a {
        proxy_pass http://127.0.0.1:8080/;
    }
    location ^~ /static/ {
        include /etc/nginx/mime.types;
        root /media/biology/swamps/frog-migration/app-a/; # this is a totally different path than app-b
    }

    location /app-b {
        proxy_pass http://127.0.0.1:8081/;
    }
    location ^~ /static/ {
        include /etc/nginx/mime.types;
        root /home/debian/projects/crystallography/web/app-b/;
    }
}

这显然与app-b的静态文件夹冲突,所以nginx -t自然会失败:

nginx: [emerg] duplicate location "/static/" in /etc/nginx/sites-enabled/proxy-pass.conf:24
nginx: configuration file /etc/nginx/nginx.conf test failed
  1. 服务器定义重复(这对我来说听起来不是个好主意):
server {
    listen 80;
    listen [::]:80;

    root /var/www;
    server_name my.server.org;

    access_log /var/log/nginx/access.log;
    error_log /var/log/nginx/error.log;

    location /app-a {
        proxy_pass http://127.0.0.1:8080/;
    }
    location ^~ /static/ {
        include /etc/nginx/mime.types;
        root /media/biology/swamps/frog-migration/app-a/;
    }
}

server {
    listen 80;
    listen [::]:80;

    root /var/www;
    server_name my.server.org;

    access_log /var/log/nginx/access.log;
    error_log /var/log/nginx/error.log;

    location /app-b {
        proxy_pass http://127.0.0.1:8081/;
    }
    location ^~ /static/ {
        include /etc/nginx/mime.types;
        root /home/debian/projects/crystallography/web/app-b/;
    }
}

语法没问题,但nginx -t 有一些警告:

nginx: [warn] conflicting server name "my.server.org" on 0.0.0.0:80, ignored
nginx: [warn] conflicting server name "my.server.org" on [::]:80, ignored
nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful

但最重要的是,app-b 无法再访问(返回 404)。

问题

使用nginx,我怎样才能让两个(当然更多)不同的应用程序(位于同一主机上的两个不同路径)彼此相邻,在它们自己的气泡中并通过它们的拥有静态子文件夹(即两个应用的静态文件之间没有干扰)?

【问题讨论】:

    标签: nginx-reverse-proxy static-files


    【解决方案1】:

    我终于找到了这个解决方案,其中一台服务器正在运行,但我不是 100% 满意,因为我想避免 alias 指令,因为 path traversal vulnerability

    免责声明:所以请不要忘记别名位置中的尾部斜杠。

    server {
        listen 80;
        listen [::]:80;
    
        #root /var/www;
        server_name server.domain.org;
    
        access_log /var/log/nginx/access.log;
        error_log /var/log/nginx/error.log;
    
        location /app-a {
            proxy_pass http://127.0.0.1:8080/;
            location /app-a/static/ {
                include /etc/nginx/mime.types;
                alias /media/biology/swamps/frog-migration/app-a/static/;
            }
        }
    
        location /app-b {
            proxy_pass http://127.0.0.1:8081/;
            location /app-b/static/ {
                include /etc/nginx/mime.types;
                alias /home/debian/projects/crystallography/web/app-b/static/;
            }
        }
    
    }
    

    特别是,它不适用于root 指令;因为它发送的页面没有任何静态文件(这些静态文件上的错误 404,我不明白为什么):

    server {
        listen 80;
        listen [::]:80;
    
        #root /var/www;
        server_name server.domain.org;
    
        access_log /var/log/nginx/access.log;
        error_log /var/log/nginx/error.log;
    
        location /app-a {
            proxy_pass http://127.0.0.1:8080/;
            location /app-a/static/ {
                include /etc/nginx/mime.types;
                root /media/biology/swamps/frog-migration/app-a/;
            }
        }
    
        location /app-b {
            proxy_pass http://127.0.0.1:8081/;
            location /app-b/static/ {
                include /etc/nginx/mime.types;
                root /home/debian/projects/crystallography/web/app-b/;
            }
        }
    
    }
    

    除了上面的工作解决方案之外,我还必须将我的 Flask 应用程序中的静态路径更改为:
    /app-a/static,而不仅仅是/static for app-a 和
    /app-b/static/static 用于 app-b。

    但是通过这样做,您肯定希望将您的 app-aapp-b 字符串放在环境变量中的某个位置,而不是硬编码它们。

    【讨论】:

      猜你喜欢
      • 2014-01-26
      • 2016-10-25
      • 1970-01-01
      • 2023-04-11
      • 2016-01-28
      • 2018-10-23
      • 2021-12-02
      • 2020-09-14
      • 2019-06-27
      相关资源
      最近更新 更多