6

I am trying to get hands around ingress routing to deploy multiple ReactJS application using one public ip address. Using SpeedyMath app available at https://github.com/pankajladhar/speedy-math.git with below routing file trying to access this app as http://myapps.centralus.cloudapp.azure.com/speedymath displays a white screen. From browser logs what i see is http://myapps.centralus.cloudapp.azure.com/static/js/bundle.js net::ERR_ABORTED 404 (Not Found). I notice index.html getting loaded but errors "Failed to load resource" at line <script type="text/javascript" src="/static/js/bundle.js"></script></body>

ingress-routing.yml:

apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: myapps-ingress
  annotations:
    nginx.org/server-snippet: "proxy_ssl_verify off;"
    nginx.ingress.kubernetes.io/rewrite-target: /
spec:
  rules:
  - http:
      paths:
      - path: /speedymath
        backend:
          serviceName: speedymath-service
          servicePort: 80

The same application loads properly when the routing file is updated for path from "/speedymath" to "/". But this does not help me in building different routing rules based on incoming url

apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: myapps-ingress
  annotations:
    nginx.org/server-snippet: "proxy_ssl_verify off;"
    nginx.ingress.kubernetes.io/rewrite-target: /
spec:
  rules:
  - http:
      paths:
      - path: /
        backend:
          serviceName: speedymath-service
          servicePort: 80

Appreciate your help here

Revanth
  • 299
  • 5
  • 13

4 Answers4

3

My issue got resolved with couple of things:

  1. As @mk_sta stated, path as path: /speedymath(/|$)(.*) and nginx.ingress.kubernetes.io/rewrite-target: /$2

  2. To handle the context issue with ReactJS app, updated package.json to include "homepage": ".". This will update all links and paths to refer from current directory.

Revanth
  • 299
  • 5
  • 13
  • 5
    Can you please elaborate on `"homepage"`. I am facing exactly the same issue. – deepdive Feb 07 '20 at 00:46
  • 1
    I tried your approach but it didn't work! I still need to append `/` to access the app – deepdive Feb 07 '20 at 04:05
  • @deepdive with "homepage" attribute in the package.json in your app you are setting the env variable "PUBLIC_URL", you have many ways to do this. If you put "." it will take the relative path. This fix part of my issue, but not all. – Frank Escobar Aug 25 '20 at 11:23
1

I've managed to reproduce the issue in the similar user case with Nginx Ingress controller 0.25.1 version:

$ kubectl exec -it $(kubectl get po -l component=controller|awk '{print $1}'| sed '1d') -- /nginx-ingress-controller

A few concerns that might help you to resolve a problem:

FYI, since 0.22.0 version of Nginx Ingress was announced, some significant changes in Rewrite annotations being propagated that are not compatible with previous configurations, read more here.

If you are using more latest Ingress controller release, then you would probably need to slightly improve the origin Ingress definition, according to the documentation:

apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: myapps-ingress
  annotations:
    nginx.org/server-snippet: "proxy_ssl_verify off;"
    nginx.ingress.kubernetes.io/rewrite-target: /$2
spec:
  rules:
  - http:
      paths:
      - path: /speedymath(/|$)(.*)
        backend:
          serviceName: speedymath-service
          servicePort: 80

Afterwards, you might be able to reach the application endpoint, however I have added Trailing slash in my target URL, instructing Nginx engine to properly serve some static content; looking at your URL:

http://myapps.centralus.cloudapp.azure.com/speedymath/

Following this discussion, you can even redirect all requests to a non trailing location, adjusting appropriate Configuration snippet annotation to the source Ingress resource:

nginx.ingress.kubernetes.io/configuration-snippet: |
  rewrite ^(/speedymath)$ $1/ permanent;
Nick_Kh
  • 5,089
  • 2
  • 10
  • 16
  • 1
    Tried above snippet with regex for path and trailing slash for the url, still the same blank screen for reactapp – Revanth Oct 15 '19 at 19:36
  • My thought is that when path in ingress is being used, some how reactJS app is loosing the context to load the elements, does mentioning path in ingress file change anything on the application? like changing the directory and looking at a wrong place while building html for the page or pulling files to the browser? – Revanth Oct 15 '19 at 19:46
  • Ingress controller reads the inputs from `Ingress` and adds the rewrite rule to the nested Nginx Pod, like: `rewrite "(?i)/speedymath(/|$)(.*)" /$2 break;`, therefore the root path for the origin application should not be changed. – Nick_Kh Oct 16 '19 at 07:41
  • This is pretty new area to me, can you please elaborate and help in uderstanding. what does $2 hold assigned to rewrite, does this param's value get fed from the regex mentioned against path? My understanding with "nginx.ingress.kubernetes.io/rewrite-target:" is when url being directed to ingress resource for routing, this annotation will decide on where it should be redirected on the target host, please correct me. Any references where to find the relation between path and rewrite would be of a great help. – Revanth Oct 16 '19 at 15:24
  • You can find [here](https://kubernetes.github.io/ingress-nginx/examples/rewrite/#rewrite-target) a good example for rewrite function, leveraging capture groups usage. – Nick_Kh Oct 18 '19 at 07:57
0

The last time I did this my annotation was a bit different. That's the only difference I see between what worked for me.

annotations:
    ingress.kubernetes.io/rewrite-target: /
Jake Luby
  • 1,718
  • 5
  • 16
0

I also had this problem. It's caused because you specified a path in your ingress (in your case speedymath) but the react application will try to access the root path.

This can be solved by adding an environment variable (PUBLIC_URL) assigned with the same path you specified on ingress (would be \speedymath\ in your case) in your deployment (or pod) yaml like this:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: myapp
  labels:
    app: myapp
spec:
  replicas: 1
  selector:
    matchLabels:
      app: myapp
  template:
    metadata:
      labels:
        app: myapp
    spec:
      containers:
      - name: myapp
        env:
        - name: PUBLIC_URL
          value: "/<MY_INGRESS_PATH>/"
        image: myapp/image:latest
        ports:
        - containerPort: 80

Hope this can help others!