2017-08-13 224 views
3

我有一個角度應用程序運行在一個docker ubuntu鏡像中,安裝了nginx。我想將此映像部署到Kubernetes,並使用nginx代理將所有對/ api的調用重定向到Kubernetes中的後端服務。nginx proxy_pass導致404未找到頁面

我的靜態Web資源趴在/ var/www/html等我添加下面的配置到/etc/nginx/conf.d:

upstream backend-service { 
    server backend-service:8080; 
} 

server { 
    listen 80; 

    location/{ 
    try_files $uri $uri/ /index.html; 
    } 

    location ^~ /api { 
    proxy_pass http://backend-service; 
    } 
} 

上訪問前端服務/或/#/儀表板返回我的Angular頁面的預期組件,但對/ api/v1/data的調用僅顯示默認的nginx 404 Not Found頁面

我需要修改哪些後端調用重定向到後端?

我使用nginx的1.10.3在Ubuntu 16.04和我的前端Dockerfile看起來是這樣的:

FROM ubuntu:16.04 

# Install curl, nodejs and nginx 
RUN apt-get update && \ 
    apt-get install -y curl && \ 
    curl -sL https://deb.nodesource.com/setup_8.x | bash - && \ 
    apt-get install -y nodejs nginx && \ 
    rm -rf /var/lib/apt/lists/* 

# Create directory 
RUN mkdir -p /usr/src/app 
WORKDIR /usr/src/app 

# Copy and build rest of the app 
COPY . /usr/src/app 
RUN npm install 
RUN node_modules/@angular/cli/bin/ng build --prod 
RUN cp -a dist/. /var/www/html 

# Configure and start nginx 
COPY frontend.conf /etc/nginx/conf.d 

EXPOSE 80 

CMD ["nginx", "-g", "daemon off;"] 

編輯:關於後端服務信息

後端服務聽得到並在/ api/v1/data上發佈請求,並可通過名爲後端服務的服務在Kubernetes中進行訪問。

EDIT2:Nginx的access.log的

https://gist.github.com/Steffen911/a56e3175bf12e511048d01359a475724

172.17.0.1 - - [13/Aug/2017:13:11:40 +0000] "GET/HTTP/1.1" 200 380 "-" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/60.0.3112.90 Safari/537.36" 
172.17.0.1 - - [13/Aug/2017:13:11:40 +0000] "GET /styles.d41d8cd98f00b204e980.bundle.css HTTP/1.1" 200 0 "http://192.168.99.100:30497/" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/60.0.3112.90 Safari/537.36" 
172.17.0.1 - - [13/Aug/2017:13:11:40 +0000] "GET /inline.c9a1a6b995c65c13f605.bundle.js HTTP/1.1" 200 1447 "http://192.168.99.100:30497/" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/60.0.3112.90 Safari/537.36" 
172.17.0.1 - - [13/Aug/2017:13:11:40 +0000] "GET /polyfills.117078cae3e3d00fc376.bundle.js HTTP/1.1" 200 97253 "http://192.168.99.100:30497/" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/60.0.3112.90 Safari/537.36" 
172.17.0.1 - - [13/Aug/2017:13:11:40 +0000] "GET /main.3e9a37b4dd0f3bf2465f.bundle.js HTTP/1.1" 200 64481 "http://192.168.99.100:30497/" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/60.0.3112.90 Safari/537.36" 
172.17.0.1 - - [13/Aug/2017:13:11:40 +0000] "GET /vendor.146173c1a99cc2172a5f.bundle.js HTTP/1.1" 200 661261 "http://192.168.99.100:30497/" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/60.0.3112.90 Safari/537.36" 
172.17.0.1 - - [13/Aug/2017:13:11:40 +0000] "GET /api/v1/data/ HTTP/1.1" 404 209 "http://192.168.99.100:30497/" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/60.0.3112.90 Safari/537.36" 
172.17.0.1 - - [13/Aug/2017:13:11:40 +0000] "GET /assets/home.jpg HTTP/1.1" 200 2608 "http://192.168.99.100:30497/" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/60.0.3112.90 Safari/537.36" 
172.17.0.1 - - [13/Aug/2017:13:11:40 +0000] "GET /assets/busy.gif HTTP/1.1" 200 48552 "http://192.168.99.100:30497/" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/60.0.3112.90 Safari/537.36" 
172.17.0.1 - - [13/Aug/2017:13:11:40 +0000] "GET /assets/background_light.png HTTP/1.1" 200 170599 "http://192.168.99.100:30497/" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/60.0.3112.90 Safari/537.36" 
172.17.0.1 - - [13/Aug/2017:13:11:40 +0000] "GET /assets/google.svg HTTP/1.1" 200 2232 "http://192.168.99.100:30497/" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/60.0.3112.90 Safari/537.36" 
172.17.0.1 - - [13/Aug/2017:13:11:40 +0000] "GET /assets/email.svg HTTP/1.1" 200 1596 "http://192.168.99.100:30497/" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/60.0.3112.90 Safari/537.36" 
172.17.0.1 - - [13/Aug/2017:13:11:40 +0000] "GET /favicon.ico HTTP/1.1" 200 198 "http://192.168.99.100:30497/" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/60.0.3112.90 Safari/537.36" 
172.17.0.1 - - [13/Aug/2017:13:11:44 +0000] "GET /api/v1/data/ HTTP/1.1" 404 209 "-" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/60.0.3112.90 Safari/537.36" 

error.log文件是空的。

EDIT3:nginx的新版本和其他SO線程

我也試過nginx的1.12.1,它顯示了相同的行爲。這個問題的答案也沒有幫助:nginx proxy_pass 404 error, don't understand why

Edit4:我上傳再現GitHub上

https://github.com/Steffen911/nginx-sample

+0

你沒有發佈任何有關後端服務?它期望什麼網址?使用/ api /還是不使用? –

+0

@TarunLalwani我更新了問題。它預計會打電話給/ api/v1/data –

+0

發佈您的nginx日誌也 –

回答

2

從你的nginx的故障排除,看來你有nginx的配置文件沒有有效的效果 - 你報告接受404 Not Found誤差比索引頁之外的一切,所有的指令,從try_fileslocation /,到更具體的location ^~ /api中的proxy_passreturn 200 test,沒有效果。

因此,問題似乎在Dockerfile - 看起來大多數其他NGINX + Docker教程刪除默認配置(例如,與RUN rm /etc/nginx/conf.d/default.conf),而您的文件丟失任何此類刪除。

事實上,Debian/Ubuntu似乎有一個名爲/etc/nginx/sites-available/etc/nginx/sites-enabled可疑程序,對不規範的目錄,其默認情況下,必須包含一個放肆listen 80 default_server一個default文件,有效地採取優先的任何其他listen同樣的港口在沒有更具體的server_name


因此,有多個獨立的解決方案:


  • 不要使用從根本上破包,比如由於Debian/Ubuntu提供的服務。我曾經花了很多時間拉我的頭髮,試圖找出爲什麼我的配置不起作用,只是要注意,即使從emacstest.conf~的備份文件通過Debian的默認include /etc/nginx/sites-enabled/*;包括在Debian中。 啓用網站是邪惡的。

    注意NGINX provides official binary packages for most distributions,這不會有這樣的問題,因爲它不會嘗試在其/etc/nginx/conf.d/default.conf定義default_server,而不是做一個listen 80;server_name localhost;,在大多數走出自己的方式自動本身情況。

    例如,將FROM ubuntu:16.04替換爲您的Dockerfile中的FROM nginx即可使用NGINX官方圖片。


  • 如果仍然使用nginx的來自於Debian/Ubuntu,確保RUN rm /etc/nginx/sites-enabled/defaultDockerfile刪除default_serverlisten

  • 使用server_name指令與listen指令與default_server參數來定義基於主機的服務器,可能在一起了。

    注意,在配置重複server_name規範結果警告(與[warn]嚴重性),但重複default_server配置錯誤([emerg]嚴重程度),這可能有助於解決該問題早。

2

呼叫我的問題,一個最小的例子/ API/V1 /數據只顯示默認的nginx 404 Not Found頁面

proxy_pass指令不太可能產生默認的nginx 404 Not Found錯誤頁面本身。

  • 404可能由上游產生,在這種情況下,不存在進一步的說明,nginx的將簡單地從上游傳播消息。如果你在404上有一個nginx簽名,那麼這意味着上游也在運行nginx,可能會讓你大吃一驚,揭示配置的罪魁禍首。

  • 如果404實際上是由nginx生成的,那麼它可能是location不匹配的情況。嘗試將return 200 thisisatest;代替proxy_pass來解決問題。

    然而,在特定情況下,location ^~ /api {是一個幾乎不可能的指令不匹配/api/v1/data/請求URI - 我能想到的唯一的事情是,如果你可能有一個try_filesserver配置任何其他location指令之外,這可能會使所有的位置指令無效。您確定您的try_files完全包含在location /的上下文中嗎?

+0

我知道我的上游正在運行不基於nginx的nodejs docker容器。我也嘗試了你的第二個建議,並用返回200代替了proxy_pass;但我仍然得到一個404不是「/」的東西。我只添加了我在此粘貼的配置文件。默認的nginx配置是否覆蓋了可能會破壞我預期行爲的事情? –

+0

我還添加了一個例子,將我的問題完全複製到 –

+0

@SteffenSchmitz,哇,這真的很奇怪,您可以像這樣重現它;因爲即使使用了'return 200',你仍然會得到404,但我唯一的建議是,你仍舊有一箇舊的配置文件,它優先於你的新配置文件;就我個人而言,我遇到了一個問題,我嘗試在'/ etc/nginx/sites-enabled'中修改文件,備份文件(例如test.conf〜)優先於'test.conf' ,因此事情會非常奇怪。 – cnst