除了HTML页面之外,NGINX都给出了404错误

我将nginx设置为泊坞窗容器中的反向代理,以链接到容器外部的站点。 我有一个虚拟主机configuration设置如下(我尝试添加^家庭助理的位置之前):

server { # simple reverse-proxy listen 80; location / { proxy_pass http://192.168.1.99:6789; } location ^~ /home-assistant { proxy_pass http://192.168.1.99:8123/; } location /calibre-web/ { proxy_pass http://192.168.1.99:8181/; } } 

对于家庭助理和口径网站,页面加载,但我得到404错误的所有其他项目(图像,CSS等)。 如果我尝试点击应用程序中的链接,它将链接到192.168.1.99 /文件,而不是192.168.1.99 / site-folder /文件 。 以下是日志中的一些logging(注意一个200响应和其他404响应)。 我在这里做错了什么? 先谢谢您的帮助。

 192.168.1.6 - randy [15/Aug/2016:03:15:42 +0000] "GET /frontend/panels/dev-template-0a099d4589636ed3038a3e9f020468a7.html HTTP/1.1" 404 199 "http://192.168.1.99/home-assistant/" "Mozilla/5.0 (X11; CrOS x86_64 8350.60.0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/52.0.2743.85 Safari/537.36" 192.168.1.6 - randy [15/Aug/2016:03:15:42 +0000] "GET /frontend/panels/logbook-66108d82763359a218c9695f0553de40.html HTTP/1.1" 404 199 "http://192.168.1.99/home-assistant/" "Mozilla/5.0 (X11; CrOS x86_64 8350.60.0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/52.0.2743.85 Safari/537.36" 192.168.1.6 - randy [15/Aug/2016:03:17:54 +0000] "GET /home-assistant/ HTTP/1.1" 200 1654 "-" "Mozilla/5.0 (X11; CrOS x86_64 8350.60.0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/52.0.2743.85 Safari/537.36" 192.168.1.6 - randy [15/Aug/2016:03:17:55 +0000] "GET /static/icons/favicon-192x192.png HTTP/1.1" 404 91 "http://192.168.1.99/home-assistant/" "Mozilla/5.0 (X11; CrOS x86_64 8350.60.0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/52.0.2743.85 Safari/537.36" 192.168.1.6 - randy [15/Aug/2016:03:17:55 +0000] "GET /static/core-457d5acd123e7dc38947c07984b3a5e8.js HTTP/1.1" 404 91 "http://192.168.1.99/home-assistant/" "Mozilla/5.0 (X11; CrOS x86_64 8350.60.0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/52.0.2743.85 Safari/537.36" 

这里是我的根nginx.conf的副本 。 我猜这个错误在这里,我只是不知道在哪里。

您正尝试从原始应用程序未知的位置proxy_pass请求。 在docker集装箱应用程序中,仍然认为它是从网站根目录( http://192.168.1.99:8123/ )访问的,所以它会生成所有相对于/ URL,而不是你的/home-assistant//calibre-web/

有很多方法可以解决这个问题,你应该select最适合你的方法:

1.replace代理html中的链接

首先,它将取代从代理应用程序接收到的每一个链接,然后将结果提交给客户端,可以使用ngx_http_sub_module 。 它没有默认启用,所以如果你的发行版没有它,你可能需要从源代码编译nginx (为了检查运行nginx -V这个模块的可用性,它应该在configuration参数的某处显示--with-http_sub_module )。

如果您select此方法,请将以下指令添加到您的configuration中:

 location ^~ /home-assistant { rewrite ^/home-assistant(/.*)$ $1 break; proxy_pass http://192.168.1.99:8123/; sub_filter "<head>" "<head><base href=\"${scheme}://${host}/home-assistant\">"; } 

2.更改容器内的应用程序path

将Docker容器中的应用程序移动到/home-assistant而不是root,所以它会生成与该path相关的服务内容中的所有URL而不是root / 。 这是一个显而易见的(也许是最简单的)解决scheme,根本不需要触摸nginxconfiguration(而是在Docker中编辑configuration)

3.根据Referer头select上游

根据Referer头确定应该使用哪个上游。 从这里采取 。 看起来很聪明,虽然我不会在生产中使用它(注意它只适用于css / js文件)。

 location ~* ^/(css|js)/.+\.(css|js)$ { #checking if referer is from home-assistant if ($http_referer ~ "^.*/home-assistant"){ return 417; } #checking if referer is from calibre-web if ($http_referer ~ "^.*/calibre-web"){ return 418; } } error_page 417 /home-assistant$request_uri; error_page 418 /calibre-web$request_uri; location ^~ /home-assistant { proxy_pass http://192.168.1.99:8123/; } location /calibre-web { proxy_pass http://192.168.1.99:8181/; } 

如果我是你的话,我会select#2 – 在容器中移动应用程序,作为最简单和最容易出错的方式来获得你所需要的。

PS我完全忘了你可以直接从硬盘上提供静态文件,因为你的后端和nginx在同一台服务器上。 这将需要一些与应用程序相关的configuration,但是结果是您将获得最有效的解决scheme。

一种解决scheme可能不是在proxy_pass指令中传递URI:

 location ^~ /home-assistant { proxy_pass http://192.168.1.99:8123; } location ^~ /calibre-web/ { proxy_pass http://192.168.1.99:8181; } 

注意proxy_pass语句中的端口号后面的缺less/字符。 这意味着nginx会将发送给服务器的URI传递给应用服务器。

使用/字符(URI),它将用该字符replace请求URI。

此行为logging在http://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_pass