我正在尝试使用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错误,因为该页面正在提交对驻留在上游容器“编辑器”中的静态资源的请求。
我对Nginx还是很陌生,但我想它会收到带有url的请求:
http://example.com/static/css/2.3d394414.chunk.css
Nginx无法知道相应的CSS位于editor
容器内部。如何修改配置以解决此问题?我已经看到了一些配置,这些配置提供了通往任何静态资产的通用路径,但是我需要一个可以处理Docker容器内资产的解决方案。
答案 0 :(得分:1)
如果我正确理解,您在上游的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 – try files on multiple named location or server
希望有帮助。
答案 1 :(得分:1)
如果其他任何人遇到相同的问题,这是一个附加的答案,以及@ b0gusb发布的答案。当您将Docker容器作为上游应用程序时,这是一个解决方案。 dashboard
和editor
例如是包含create-react-app个应用程序和nginx服务器的容器。
首先,通过设置package.json中的index.html
字段,更改由create-react-app
生成的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/;
}
答案 2 :(得分:0)
将 /编辑器配置置于 / 配置上方。
Nginx从上到下执行检查,因此,最上面的根配置( / )会将所有内容路由到错误的服务器。
切换块位置并重新启动/重新加载nginx配置。
答案 3 :(得分:0)
实际上,为便于配置,您可以按照以下步骤操作:
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可以重写,希望对您有所帮助。