"rewrite-target" failing when routing to React.js app on nginx server

1/3/2021

I have a React app which I build and dockerize to be hosted on a nginx server.

FROM nginx:latest
COPY build /usr/share/nginx/html

I then create a simple deployment and service for it (which I very much doubt are the problem). Next I create an nginx ingress.

apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
  name: my-app-ingress
  annotations:
    kubernetes.io/ingress.class: "nginx"
    nginx.ingress.kubernetes.io/ssl-redirect: "false"
    nginx.ingress.kubernetes.io/rewrite-target: /
spec:
  rules:
  - host: <MY_NGINX_CONTROLLER_EXTERNAL_IP>.xip.io
    http:
      paths:
      - backend:
          serviceName: my-app-service
          servicePort: 80
        path: /myapp   

But when I call <MY_NGINX_CONTROLLER_EXTERNAL_IP>.xip.io/myapp I get a 404.

When I change path: /myapp to path: / I can reach my app with no problems on <MY_NGINX_CONTROLLER_EXTERNAL_IP>.xip.io

I have tried numerous variations of rewrite-target and path like /$1 and /myapp/(.*) but it makes no difference.

I believe the problem lies with using the nginx.ingress.kubernetes.io/rewrite-target annotation to route to a React app. Because using that annotation for any other service on my cluster works just fine.

Others users seem to have similar problems: https://github.com/kubernetes/ingress-nginx/issues/3770#. But I was unable to find a solution.

A workaround would be to change the basename and homepage attributes within my react app and then update all routes. Then I would not need rewrite-target at all. But making it work with rewrite-target would be much cleaner, especially considering that the path/subdirectory will have to change regularly for my app.

-- 2um9YJ6haZ7wKP4m
kubernetes
kubernetes-ingress
nginx
nginx-ingress
reactjs

1 Answer

1/4/2021

I got it working now. With two additional steps "rewrite-target" annotation is not required at all and can be removed from the ingress resource.

Step 1: Change the base URL within the react app. See how to do this here.

Step 2: Copy the react build into the corresponding subdirectory of /usr/share/nginx/html in the Dockerfile:

FROM nginx:latest
COPY build /usr/share/nginx/html/myapp
-- 2um9YJ6haZ7wKP4m
Source: StackOverflow