Docker 中的 NGINX 缓存 IP 地址并提供错误的 Content-Type

2024-05-13

Summary:
我想让NGINX(不是NGINX Plus)通过使用变量从DNS名称重新解析IP地址proxy_pass(如建议的这篇 Nginx 官方文章“在变量中设置域名”部分 https://www.nginx.com/blog/dns-service-discovery-nginx-plus/)。但是当我这样做时,它不会设置/转发正确的Content-Type标题,但始终使用text/html, for .css, .js等文件。

我的设置:
我有一个前端和一个后端服务在单独的 Docker 容器中运行(将在生产中部署到 OpenShift)。还有第三个容器正在运行nginx:latest(v1.19.9 截至今天)并充当反向代理,转发对/my-app到前端和/my-app/api到后端容器。 NGINX 反向代理已使用其 DNS 名称将它们设置为上游服务器。 所有三个容器都在同一个自定义 Docker 网络中运行,因此解析本身可以正常工作 - 但仅限于(重新)启动 NGINX 时。

问题:
当前端或后端容器重新启动时,它可能会获得新的 IP 地址。由于 NGINX 缓存 IP 地址,我得到了502当我打电话给他们时。我希望 NGINX 能够更频繁地重新解析 IP 地址,就像 NGINX Plus 那样。这就是问题所在Content-Type当我尝试让 NGINX 重新解析 DNS 名称时出现了。

配置:
这是我的 NGINX 配置(仅简化为相关内容):

  index    index.html index.htm;

  upstream upstream_frontend {
    server frontend:8080;
  }

  upstream upstream_backend {
    server backend:8000;
  }

  server {
    listen       8080;
    root         /usr/share/nginx/html;

    try_files    $uri$args $uri$args/ $uri $uri/ /index.html =404;
    
    rewrite ^/my-app$ $scheme://$http_host/my-app/ permanent;

    location /my-app {
      resolver 127.0.0.11 ipv6=off valid=1s;

      proxy_set_header X-Real-IP $remote_addr;
      proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
      proxy_set_header X-Forwarded-Proto  $scheme;
      proxy_set_header X-NginX-Proxy true;
      proxy_ssl_session_reuse off;
      proxy_set_header Host $http_host;
      proxy_redirect off;

      proxy_http_version 1.1;
      proxy_pass_request_headers on;
      proxy_pass_header Content-Type;

#     Attempt #1, NOT working: using a variable and an upstream server setup
      set $frontend_var "http://upstream_frontend/";
      proxy_pass http://$frontend_var;

#     Attempt #2, NOT working: using a variable and directly using the container name
#      set $frontend_var "http://frontend:8080/";
#      proxy_pass $frontend_var;

#     Attempt #3, working fine:  using NO variable and an upstream server setup, , but no DNS re-resolving happening :-(
#      proxy_pass http://upstream_frontend/;

#     Attempt #4, working fine:  using NO variable and directly using the container name, but no DNS re-resolving happening :-(
#      proxy_pass http://frontend:8080/;
    }

    location /my-app/api {
      resolver 127.0.0.11 ipv6=off valid=1s;

      proxy_set_header X-Real-IP $remote_addr;
      proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
      proxy_set_header X-Forwarded-Proto  $scheme;
      proxy_set_header X-NginX-Proxy true;
      proxy_ssl_session_reuse off;
      proxy_set_header Host $http_host;
      proxy_redirect off;

#     Attempt #1, NOT working: using a variable and an upstream server setup
      set $backend_var "http://upstream_backend/api";
      proxy_pass http://$backend_var;

#     Attempt #2, NOT working:  using a variable and directly using the container name
#      set $backend_var "http://backend:8000/api";
#      proxy_pass http://$backend_var;

#     Attempt #3, working fine:  using NO variable and an upstream server setup, , but no DNS re-resolving happening :-(
#      proxy_pass http://upstream_backend/api;

#     Attempt #4, working fine:  using NO variable and directly using the container name, but no DNS re-resolving happening :-(
#      proxy_pass http://backend:8000/api;
    }
  }

(请注意location /my-app {...}/在结束时proxy_pass,因为前端由/my-app,而前端容器本身也由 NGINX 提供服务,直接在...:8080/,没有/my-app上下文路径。我们对正在监听的后端容器有相同的设置:8000,但是当呼叫转接到它时,我们将删除/my-app从他们那里直接到达容器...:8000/api.)

NGINX 正在端口上运行9000当我使用上面的内容打开 http://localhost:9000/my-app 时尝试#1 or 尝试#2 the .css, .js、图像文件等均由Content-Type: text/html,这会阻止浏览器正确渲染页面,并在调试器窗格中显示如下消息:

The stylesheet http://localhost:9000/my-app/static/css/main.df1d2133.chunk.css  was not loaded because its MIME type, ”text/html“ is not ”text/css"

起初我以为proxy_pass_header Content-Type;会解决这个问题,但这也没有帮助。

然后我也学到了这个 NGINX 错误单 https://trac.nginx.org/nginx/ticket/1370 that “在 proxy_pass 中使用变量时,如果指定了 URI,则会按原样传递到服务器,替换原始请求 URI。”。这似乎是一个可能的原因Content-Type我这里有问题。

另外,正如你在配置中看到的,我设置了 Docker DNS IP:resolver 127.0.0.11 ipv6=off valid=1s;。我也尝试过将其设置在location阻止,这也没有帮助。

问题:
那么如何在 NGINX(开源)中重新解析 DNSwith正确的Content-Type还设置吗?我不have使用上游服务器,这样我就可以摆脱它们,这应该是可能修复的一部分。

P.S.:
我不能按照其他 StackOverflow 评论中的建议添加单独的location阻止“追溯”修复Content-Type取决于文件夹、文件名等,因为这是一个不断发展的项目,我担心它需要我定期向 NGINX 配置添加此类修补程序。

EDIT:
我发布的配置包含在 NGINX 的 Docker 容器的配置文件中(就是这个),以防您想知道一些“丢失”的设置:

user  nginx;
worker_processes  1;

error_log  /var/log/nginx/error.log warn;
pid        /var/run/nginx.pid;


events {
    worker_connections  1024;
}


http {
    include       /etc/nginx/mime.types;
    default_type  application/octet-stream;

    log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
                      '$status $body_bytes_sent "$http_referer" '
                      '"$http_user_agent" "$http_x_forwarded_for"';

    access_log  /var/log/nginx/access.log  main;

    sendfile        on;

    keepalive_timeout  65;

    # This line includes my configuration above
    include /etc/nginx/conf.d/*.conf;
}

这不是问题Content-Type。您正在使用proxy_pass错误地。正如您已经指出的:

在 proxy_pass 中使用变量时,如果指定了 URI,则按原样传递到服务器,替换原始请求 URI。

您当前具有以下工作配置,但您希望将其替换为变量以强制 DNS 解析:

location /my-app {
    proxy_pass http://frontend:8080/;
}

最简单的解决方案是使用rewrite...break对 URI 进行更改,并删除尾随/来自变量。

例如:

location /my-app {
    rewrite ^/my-app/?(.*)$ /$1 break;
    set $frontend_var "frontend:8080";
    proxy_pass http://$frontend_var;
}

或者,使用捕获原始请求的剩余部分正则表达式 location.

例如:

location ~ ^/my-app/?(.*)$ {
    proxy_pass http://frontend:8080/$1;
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Docker 中的 NGINX 缓存 IP 地址并提供错误的 Content-Type 的相关文章

随机推荐

  • 将jquery与nodejs一起使用时的基本错误

    我正在尝试在我的项目中使用一些jquery 当我尝试使用它时 我在复制的代码中遇到了错误 并且无法获得任何有关它的谷歌帮助 var jquery require jquery var jquery create TypeError Obje
  • 自定义DataGridView列值在失去焦点后消失

    我在 WinForms 中为我的项目创建了一个自定义 DataGridViewColumn 该控件呈现完美 但一旦我输入值并移动到另一个单元格 当我签入 CellEndEdit 时 该值就会消失并显示为 null 以下是代码 class N
  • mmap() 和锁定文件

    考虑以下代码片段 故意缺少错误处理 void foo const char path off t size int fd void ret fd open path O RDWR lockf fd F LOCK 0 ret mmap NUL
  • PushReplacement 或 PushAndRemoveUntil(Route 路线) => false 不工作

    基于页面的路由无法使用命令式 api 完成 而是提供一个没有相应页面的新列表到 Navigator pages 包 flutter src widgets navigator dart 断言失败 第 3075 行 pos 7 hasPage
  • 如何在 html 5 画布上旋转单个对象?

    我试图弄清楚如何在 html 5 画布上旋转单个对象 例如 http screencast com t NTQ5M2E3Mzct http screencast com t NTQ5M2E3Mzct 我希望每一张卡都能以不同的角度旋转 到目
  • 如何使用AWK脚本检查表的所有列数据类型? [关闭]

    Closed 这个问题需要多问focused help closed questions 目前不接受答案 在这里 我正在检查表中第一列的数据类型 但我想知道AWK中表的所有列数据类型 我尝试过 但只能获得一列数据类型 例如 Column 1
  • Facebook API 错误 100 - 无效链接

    我正在使用 Facebook API 在我的 Rails 应用程序中创建发送对话框 我只是在 Javascript 中使用 Facebook 推荐的格式 作为 HTML 中的脚本 我的问题是我得到 API Error code 100 in
  • C# MonoGame 有帮助吗? (Content.Load("入侵者");)

    我正在 MonoGame 中使用 Open GL 制作太空入侵者游戏 并且尝试加载已添加到内容文件夹中的纹理 这是一个名为 Invader 的 PNG 文件 我使用的代码是 invader Content Load
  • 配置 KnpPaginator 以与 Twitter Bootstrap 配合使用

    i m trying to apply twitter bootstrap css style to my knp pagination without modifying the vendor Is there a way to conf
  • PHP MS Word 文件页数

    实际上我正在尝试计算 ms word 文件的页数 我正在使用这个 php 脚本 但是 没有向我显示确切的结果 并且脚本不是那么快 谁能帮助我获得更好的脚本 word new COM word application if word echo
  • Html5 全屏视频

    有什么办法可以做到这一点吗 我想全屏播放视频 没有浏览器 环境width 100 height 100 保持浏览器可见 不 目前还没有办法做到这一点 我希望他们在浏览器中添加这样的未来 EDIT 现在有一个全屏API http dvcs w
  • 将启用的计算机添加到 Active Directory OU

    我正在尝试以编程方式将计算机添加到我公司的 Active Directory 我在互联网上搜索了很长时间 但找不到解决方案 My code DirectoryEntry dirEntry new DirectoryEntry LDAP OU
  • 哪个更快:堆栈分配或堆分配

    这个问题听起来可能相当简单 但这是我与另一位合作的开发人员进行的辩论 我小心翼翼地在可能的地方进行堆栈分配 而不是堆分配它们 他一边跟我说话 一边看着我 并评论说没有必要 因为他们的表现是一样的 我总是有这样的印象 堆栈的增长是恒定的时间
  • 查找矩阵内的匹配子矩阵

    我有一个 100x200 2D 数组 表示为由黑色 0 和白色 255 单元组成的 numpy 数组 它是一个位图文件 然后我有 2D 形状 最容易将它们视为字母 它们也是 2D 黑白单元格 我知道我可以天真地迭代矩阵 但这将是我的代码的
  • 为什么 RDF 中对对象使用代码而不是字符串?

    例如 entity f06574 rdfs label Orioles 或者这样的格式 tt0268252 a Movie 在任一情况下 f06574 and tt0268252是代码 而不是实体或实例的实际字符串 原因之一可能是因为同一个
  • 用掩码替换字符串模式的最快方法

    我有类似的字符串 string string key foo bar 和参数数组 params array foo gt 1 bar gt 2 如何以 string 模式替换此参数 预期结果是 string key 1 2 首先 您需要重写
  • StackExchange.Redis的正确使用方法

    这个想法是使用更少的连接和更好的性能 连接会随时过期吗 对于另一个问题 redis GetDatabase 打开新连接 private static ConnectionMultiplexer redis private static ID
  • 通过 Google Play 服务撤销驱动器访问权限

    有没有办法撤销通过 Google Play 服务授予的驱动器访问权限 参考这篇文章 https developer android com google auth api client html https developer androi
  • Scala:如何将可变参数指定为类型?

    代替 def foo configuration String String 我希望能够写 type Configuration String String def foo configuration Configuration 主要用例是
  • Docker 中的 NGINX 缓存 IP 地址并提供错误的 Content-Type

    Summary 我想让NGINX 不是NGINX Plus 通过使用变量从DNS名称重新解析IP地址proxy pass 如建议的这篇 Nginx 官方文章 在变量中设置域名 部分 https www nginx com blog dns