[英]Can't serve static assets from docker containers behind Nginx reverse proxy
我正在嘗試使用 Nginx 作為反向代理來為兩個容器提供服務。 這是我的 Nginx conf 文件的一部分:
upstream dashboard {
server dashboard:80;
}
upstream editor {
server editor:80;
}
server {
listen 80;
server_name example.com;
location / {
proxy_pass http://dashboard;
}
location /editor/ {
rewrite ^/editor(.*)$ $1 break;
proxy_pass http://editor;
}
當我導航到瀏覽器中的/editor
url 時,我收到 404 錯誤,因為該頁面正在提交對駐留在上游容器“editor”中的靜態資源的請求。
我對 Nginx 很陌生,但我認為當它收到帶有 url 的請求時: http://example.com/static/css/2.3d394414.chunk.css
: http://example.com/static/css/2.3d394414.chunk.css
Nginx 無法知道相應的 css 位於editor
容器內。 如何修改配置以解決此問題? 我已經看到一些配置為任何靜態資產提供了通用路徑,但我需要一個可以處理 docker 容器內資產的解決方案。
如果其他人遇到同樣的問題,這里有一個額外的答案以及@b0gusb 發布的答案。 當您將 docker 容器作為上游應用程序時,這是一個解決方案。 例如, dashboard
和editor
是由create-react-app應用程序和 nginx 服務器組成的容器。
首先,更改create-react-app
生成的index.html
文件所在的目錄,通過在 package.json 中設置homepage
字段來搜索靜態資產:
{
"name": "dashboard",
"homepage": "https://example.com/dashboard",
"version": "0.1.0",
"private": true,
"dependencies": {
"react": "^16.9.0",
"react-dom": "^16.9.0",
"react-scripts": "3.1.1"
},
"scripts": {
"start": "react-scripts start",
"build": "react-scripts build",
"test": "react-scripts test",
"eject": "react-scripts eject"
},
"eslintConfig": {
"extends": "react-app"
},
"browserslist": {
"production": [
">0.2%",
"not dead",
"not op_mini all"
],
"development": [
"last 1 chrome version",
"last 1 firefox version",
"last 1 safari version"
]
}
}
使用當前最新版本的react-scripts
(3.1.1) 這將生成一個 index.html 文件,其中包含指向您的靜態資產的鏈接,這些資產預計位於dashboard
目錄中(或您在homepage
字段中的斜杠后選擇的任何名稱) )。
現在在您的 docker 文件中,您需要對構建資產進行一些移動,以便index.html
中的鏈接不會中斷。 以下是我的Dockerfile
:
FROM node:12.2.0-alpine as builder
WORKDIR /usr/src/app
ENV PATH /usr/src/app/node_modules/.bin:$PATH
COPY package.json .
RUN npm install react-scripts@3.1.1 -g
RUN npm install
COPY . .
RUN npm run build
FROM nginx:1.17.2
COPY --from=builder /usr/src/app/build/ /usr/share/nginx/html/dashboard
COPY --from=builder /usr/src/app/build/*.html /usr/share/nginx/html
EXPOSE 80
CMD [ "nginx", "-g", "daemon off;" ]
請注意, create-react-app
構建生成的靜態資產位於dashboard
目錄中, index.html
位於/usr/share/nginx/html
目錄中。 現在,您的 nginx 反向代理可以區分對各種容器的不同靜態資產的請求:
# location to handle calls by the editor app for assets
location /editor/ {
proxy_pass http://editor/editor/;
}
# location to handle calls by the dashboard app for assets
location /dashboard/ {
proxy_pass http://dashboard/dashboard/;
}
# location to handle navigation to the editor app
location /editor-path/ {
access_log /var/logs/nginx/access.log;
rewrite ^/editor-path(.*)$ $1 break;
proxy_pass http://editor/;
}
# location to handle calls to the rest/graphql api
location /api/ {
access_log /var/logs/nginx/access.log;
rewrite ^/api(.*)$ $1 break;
proxy_pass http://restserver/;
}
# location to handle navigation to the dashboard app
location / {
access_log /var/logs/nginx/access.log;
proxy_pass http://dashboard/;
}
如果我理解正確,您在editor
和dashboard
上游都有靜態資源,並且在這兩種情況下,URL 都是相同的/static/some.resource
因為您無法根據 URL 進行區分,所以您可以配置nginx
以嘗試該文件是否首先存在於dashboard
然后如果未找到,則將請求代理給editor
。
upstream editor {
server editor:80;
}
upstream dashboard {
server dashboard:80;
}
server {
location /static {
# Send 404s to editor
error_page 404 = @editor;
proxy_intercept_errors on;
proxy_pass http://dashboard
}
location @editor {
# If dashboard does not have the file try with editor
proxy_pass http://editor
}
}
希望能幫助到你。
把/上方,配置/編輯器配置。
Nginx 從上到下執行檢查,因此有可能將根配置 ( / ) 放在頂部會將所有內容路由到錯誤的服務器。
切換塊位置並重新啟動/重新加載 nginx 配置。
實際上,為了便於配置,您可以按照以下步驟操作:
upstream dashboard {
server dashboard:80;
}
upstream editor {
server editor:80;
}
server {
listen 80;
server_name example.com;
location / {
proxy_pass http://dashboard;
}
location /editor/ {
proxy_pass http://editor;
proxy_set_header Accept-Encoding "";
sub_filter "/static" "/editor/static;
sub_filter_once off;
}
sub_filter
函數會將 example.com/static/ 更改為 example.com/editor/static,但為了獲得最佳配置,您必須為所有靜態文件創建一個路徑。 喜歡:
/var/data/build/dashboard/..(可以是css、js)
/var/data/build/editor/..(可以是css、js)
我認為使用sub_filter
很好,而應用程序沒有很多要重寫的 URL,我希望這會有所幫助。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.