Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
388 views
in Technique[技术] by (71.8m points)

reactjs - How to set up nginx config for a React.js app deployed on AWS ECS with path-based routing load balancer

I have an application which consists of two containers:

  • a backend node.js server on express.js, referred to as 'app-server'
  • a front-end react.js client based on create-react-app, referred to as 'app-client'. This one uses an nginx server to set up reverse proxy for /api requests to the application - like this post describes

Both are dockerized and deployed on AWS ECS Fargate and are supposed to be hosted on the same domain example.com, just different paths, respectively /app-server and app-client. So the users would access the app via https://example.com/app-client. In the future we would like to host more apps on the same domain using path based routing.

To achieve that we have defined a rule on the Application Load Balancer listener on EC2 which looks like this:

IF
- Path is: /app-client*
- Host is: example.com

THEN
- Forward to
  - app-client-service-alb-h: 1 (100%)
  - Group-level stickiness: Off

Also tested - Path is: /app-client, without the * at the end.

I managed to adjust the backend express server to work with this scenario but I'm struggling to make the React.js app work with the path forwarding - it just shows a blank page (worked without a problem when it was hosted directly on a domain, let's say http://app-client.com).

My guess is it has something to do with the nginx config because the request URL's are correct but there are just no .html, .js and .css files there.

Dockerfile looks like this:

FROM node:11.5.0 as builder

WORKDIR /usr/src/app

ADD ./ /usr/src/app

RUN npm install && 
    npm run build


# ------------------------------------------------------
# Production Build
# ------------------------------------------------------
FROM nginx:1.16.0-alpine

COPY --from=builder /usr/src/app/build/ /usr/share/nginx/html

RUN rm -rf /etc/nginx/conf.d
COPY conf /etc/nginx

EXPOSE 80

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

Nginx config is set up this way:

server {

  listen 80;

  server_name example.com;

  location /api {
    proxy_pass https://example.com/app-server;
    proxy_pass_request_headers on;
  }   

  location / {
    root   /usr/share/nginx/html;
    index  index.html index.htm;
    try_files $uri $uri/ /index.html;
  }

  error_page   500 502 503 504  /50x.html;

  location = /50x.html {
    root   /usr/share/nginx/html;
  }

}

React app's package.json file was adjusted by adding homepage setting:

"homepage": "/app-client"

Also tried with "homepage": "https://example.com/app-client". In both scenarios requested paths look correct, for example:

https://example.com/app-client/static/js/main.32859df6.chunk.js

The problem is that there is nothing found under this address, the page is blank. That's why I am assuming that nginx config needs to be adjusted to provide the file from correct location but have no idea what to adjust (I did also test removing the "homepage" from package.json but that also didn't solve it.).

I tried changing the location to location /app-client { or location ^~ /app-client { but that didn't work:

location /app-client {
    root   /usr/share/nginx/html;
    index  index.html index.htm;
    try_files $uri $uri/ /index.html;
  }

I blindly followed many other solutions, for example:

None of them fixed the problem and I'm a rookie in that area so I'm stuck... Please help :(

------- Edited -------

The issue is solved and I'm posting the answer in case someone else finds it helpful.

The Nginx config should look like this, with appropriate rewrite defined:

server {

  listen 80;

  # All files should be at this directory; put it above location, otherwise it was looking in a wrong directory somewhere in  `/etc/...`
  root /usr/share/nginx/html;

  # Prefix app-client -> rewrite
  location /app-client {
    rewrite ^/app-client(?:/(.*))?$ /$1;
  }

  # proxy for backend server /api requests
  location /api {
    # the ending `/api` part depends on whether your server routes also start with `/api` or not, mine do hence it was required
    proxy_pass https://example.com/app-server/api; 
    proxy_pass_request_headers on;
  } 
  
  location / {
    index  index.html index.htm;
    try_files $uri $uri/ /index.html;
  }

}

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

The issue is solved and I'm posting the answer in case someone else finds it helpful.

The Nginx config should look like this, with appropriate rewrite defined:

server {

  listen 80;

  # All files should be at this directory; put it above location, otherwise it was looking in a wrong directory somewhere in  `/etc/...`
  root /usr/share/nginx/html;

  # Prefix app-client -> rewrite
  location /app-client {
    rewrite ^/app-client(?:/(.*))?$ /$1;
  }

  # proxy for backend server /api requests
  location /api {
    # the ending `/api` part depends on whether your server routes also start with `/api` or not, mine do hence it was required
    proxy_pass https://example.com/app-server/api; 
    proxy_pass_request_headers on;
  } 
  
  location / {
    index  index.html index.htm;
    try_files $uri $uri/ /index.html;
  }

}

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...