我正在尝试使用两个服务创建一个docker-compose,一个是Spring Boot后端(运行在端口8080上),另一个是在Nginx上运行的React前端。
react应用程序调用后端API,例如/ api / tests。
但是,当我运行docker compose并前端发出请求时,它总是失败并显示404错误:GET http://localhost/api/tests 404 (Not Found)
当我将前端dockerfile设置为不使用Nginx时,只是npm start
,它可以正常工作,但是我更喜欢在Nginx上使用生产版本。
当前前端dockerfile:
FROM node:11.13 as builder
RUN mkdir /usr/src/app
WORKDIR /usr/src/app
ENV PATH /usr/src/app/node_modules/.bin:$PATH
COPY package.json /usr/src/app/package.json
RUN npm install
RUN npm install react-scripts@2.1.8 -g
COPY ./package-lock.json /usr/src/app/
COPY ./public /usr/src/app/public
COPY ./src /usr/src/app/src
COPY ./nginx.conf /etc/nginx/nginx.conf
RUN npm run build
FROM nginx:1.15.10-alpine
COPY --from=builder /usr/src/app/build /usr/share/nginx/html
CMD ["nginx", "-g", "daemon off;"]
Nginx.conf:
server {
listen 80;
location / {
try_files $uri $uri/ /index.html;
add_header Cache-Control public;
expires 1d;
}
location /api {
proxy_set_header X-Forwarded-Host $host;
proxy_set_header X-Forwarded-Server $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_pass http://server:8080/;
}
}
docker-compose:
version: "3"
services:
server:
build: test-server/
expose:
- 8080
ports:
- 8080:8080
ui:
build: test-ui/
expose:
- 80
ports:
- 80:80
react应用的package.json中有一行"proxy": "http://server:8080"
。
Nginx记录以下错误:
2019/04/15 12:50:03 [error] 6#6: *1 open() "/usr/share/nginx/html/api/tests" failed (2: No such file or directory), client: 172.20.0.1, server: localhost, request: "GET /api/tests HTTP/1.1", host: "localhost", referrer: "http://localhost/"
答案 0 :(得分:1)
我发现了问题。在Docker映像的多阶段构建中,我不小心将nginx.conf文件复制到了构建器映像中,而不是生产版本中。
固定的Dockerfile现在看起来像这样:
# build environment
FROM node:11.13 as builder
RUN mkdir /usr/src/app
WORKDIR /usr/src/app
ENV PATH /usr/src/app/node_modules/.bin:$PATH
COPY package.json /usr/src/app/package.json
RUN npm install
RUN npm install react-scripts@2.1.8 -g
COPY ./package-lock.json /usr/src/app/
COPY ./public /usr/src/app/public
COPY ./src /usr/src/app/src
RUN npm run build
# production environment
FROM nginx:1.15.10-alpine
COPY --from=builder /usr/src/app/build /var/www
COPY ./nginx.conf /etc/nginx/nginx.conf
CMD ["nginx", "-g", "daemon off;"]
和nginx.conf:
server {
listen 80;
include /etc/nginx/mime.types;
root /var/www;
index index.html index.htm;
location /api {
resolver 127.0.0.11;
proxy_set_header X-Forwarded-Host $host;
proxy_set_header X-Forwarded-Server $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_pass http://server:8080$request_uri;
}
location / {
try_files $uri $uri/ =404;
}
}
答案 1 :(得分:0)
由于您正在访问api http://localhost/api/tests
,因此失败,而在docker-compose
文件中,您将api指向端口8080
。
所以尝试这个:
http://localhost:8080/api/tests
我建议您使用ENVIRONMENT VARIABLES
,以便在更改端口或其他内容时可以进行更改。然后在React中,您可以通过以下方式访问它们:
例如您可以从终端
SET REACT_APP_API_URL=http://localhost:8080
并通过
访问 process.env.REACT_APP_API_URL
或者您甚至可以在Dockerfile
或docker-compose
文件中进行设置。
答案 2 :(得分:0)
它在开发中可以正常工作,因为您有一个Webpack开发服务器将您的请求代理到8080端口("proxy": "http://server:8080"
行),但这在生产版本中已消失。
将$request_url
添加到您的proxy_pass应该对其进行修复。
location /api {
proxy_set_header X-Forwarded-Host $host;
proxy_set_header X-Forwarded-Server $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_pass http://server:8080$request_uri;
}