title: How to set up nginx config for a React.js app deployed on AWS ECS with path-based routing load balancer
body: <p>I have an application which consists of two containers:</p>
  <ul>
  <li>a backend node.js server on express.js, referred to as 'app-server'</li>
  <li>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 <code>/api</code> requests to the application - <a href="https://medium.com/@frontendfoo/docker-react-express-reverse-proxy-15d7b37f8dc2" rel="nofollow noreferrer">like this post describes</a></li>
  </ul>
  <p>Both are dockerized and deployed on AWS ECS Fargate and are supposed to be hosted on the same domain <code>example.com</code>, just different paths, respectively <code>/app-server</code> and <code>app-client</code>. So the users would access the app via <code>https://example.com/app-client</code>. In the future we would like to host more apps on the same domain using path based routing.</p>
  <p>To achieve that we have defined a rule on the Application Load Balancer listener on EC2 which looks like this:</p>
  <pre><code>IF
  - Path is: /app-client*
  - Host is: example.com
  
  THEN
  - Forward to
    - app-client-service-alb-h: 1 (100%)
    - Group-level stickiness: Off
  </code></pre>
  <p>Also tested <code>- Path is: /app-client</code>, without the <code>*</code> at the end.</p>
  <p>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 <code>http://app-client.com</code>).</p>
  <p>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.</p>
  <p>Dockerfile looks like this:</p>
  <pre><code>FROM node:11.5.0 as builder
  
  WORKDIR /usr/src/app
  
  ADD ./ /usr/src/app
  
  RUN npm install &amp;&amp; \
      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 [&quot;nginx&quot;, &quot;-g&quot;, &quot;daemon off;&quot;]
  </code></pre>
  <p>Nginx config is set up this way:</p>
  <pre><code>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;
    }
  
  }
  </code></pre>
  <p>React app's package.json file was adjusted by adding homepage setting:</p>
  <pre><code>&quot;homepage&quot;: &quot;/app-client&quot;
  </code></pre>
  <p>Also tried with <code>&quot;homepage&quot;: &quot;https://example.com/app-client&quot;</code>. In both scenarios requested paths look correct, for example:</p>
  <pre><code>https://example.com/app-client/static/js/main.32859df6.chunk.js
  </code></pre>
  <p>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 <code>&quot;homepage&quot;</code> from package.json but that also didn't solve it.).</p>
  <p>I tried changing the location to <code>location /app-client {</code> or <code>location ^~ /app-client {</code> but that didn't work:</p>
  <pre><code>location /app-client {
      root   /usr/share/nginx/html;
      index  index.html index.htm;
      try_files $uri $uri/ /index.html;
    }
  </code></pre>
  <p>I blindly followed many other solutions, for example:</p>
  <ul>
  <li><a href="https://medium.com/swlh/nginx-meets-amazon-ecs-hosting-multiple-back-end-services-using-a-single-load-balancer-61a0c047eaba" rel="nofollow noreferrer">Nginx Meets Amazon ECS: Hosting Multiple Back-End Services Using a Single Load Balancer</a></li>
  <li><a href="https://github.com/artk-dev/ecs-nginx-multi-app-setup/blob/main/nginx.conf" rel="nofollow noreferrer">Based on this config</a></li>
  </ul>
  <p>None of them fixed the problem and I'm a rookie in that area so I'm stuck... Please help :(</p>
  <p>------- Edited -------</p>
  <p>The issue is solved and I'm posting the answer in case someone else finds it helpful.</p>
  <p>The Nginx config should look like this, with appropriate rewrite defined:</p>
  <pre><code>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 -&gt; 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;
    }
  
  }
  </code></pre>