<p>I'm new to Kubernetes and I'm trying to deploy a React app to my cluster. Here's the basic info:</p>
<ul>
<li>Docker Desktop, single-node Kubernetes cluster</li>
<li>React development frontend, exposing port 3000</li>
<li>Node.js/Express backend, exposing port 8080</li>
<li>NGINX Ingress Controller, serving my React frontend on &quot;localhost:3000&quot; and routing my Fetch API requests (fetch(&quot;localhost:3000/api/...&quot;, OPTIONS)) to the backend (which works)</li>
</ul>
<p>I am having an issue when opening the React app. The Ingress Controller correctly routes to the app but the 3 bundles (bundle.js, main.chink.js, the third one which I don't remember) aren't loaded. I get the following error:</p>
<pre><code>GET http://localhost/static/js/main.chunk.js net::ERR_ABORTED 404 (Not Found) ingress (one example)
</code></pre>
<p>I understand why this error happens. The Ingress Controller correctly routes the traffic but only loads the index.html file. In this file, there are calls to 3 scripts (referring to the bundles) which aren't loaded. I understand the error, the files don't get sent to the browser so the index.html file can't load them in, but do not know how to fix it.
Does anyone have any suggestions? de and then pulled from Docker Hub. Does anybody know what a possible solution could be? For example, does deploying the build/ folder (built React app using &quot;npm run build&quot;) fix this? Do I have to use nginx inside my Dockerfile to build the container?</p>
<p>Ingress.yaml</p>
<pre><code>apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: titanic-ingress
  #labels:
      #name: titanic-ingress
spec:
  ingressClassName: nginx
  rules:
  - host: localhost
    http:
      paths:
      - path: /
        pathType: Exact
        backend:
          service:
            name: titanicfrontendservice
            port:
              number: 3000
      - path: /api
        pathType: Exact
        backend:
          service:
            name: titanicbackendservice
            port:
              number: 8080
</code></pre>
<p>Ingress controller deployment yaml</p>
<pre><code>apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-ingress
  namespace: nginx-ingress
spec:
  replicas: 1
  selector:
    matchLabels:
      app: nginx-ingress
  template:
    metadata:
      labels:
        app: nginx-ingress
     #annotations:
       #prometheus.io/scrape: &quot;true&quot;
       #prometheus.io/port: &quot;9113&quot;
    spec:
      serviceAccountName: nginx-ingress
      containers:
      - image: nginx/nginx-ingress:1.10.0
        imagePullPolicy: IfNotPresent
        name: nginx-ingress
        ports:
        - name: http
          containerPort: 80
        - name: https
          containerPort: 443
        - name: readiness-port
          containerPort: 8081
       #- name: prometheus
         #containerPort: 9113
        readinessProbe:
          httpGet:
            path: /nginx-ready
            port: readiness-port
          periodSeconds: 1
        securityContext:
          allowPrivilegeEscalation: true
          runAsUser: 101 #nginx
          capabilities:
            drop:
            - ALL
            add:
            - NET_BIND_SERVICE
        env:
        - name: POD_NAMESPACE
          valueFrom:
            fieldRef:
              fieldPath: metadata.namespace
        - name: POD_NAME
          valueFrom:
            fieldRef:
              fieldPath: metadata.name
        args:
          - -nginx-configmaps=$(POD_NAMESPACE)/nginx-config
          - -default-server-tls-secret=$(POD_NAMESPACE)/default-server-secret
          #- -v=3 # Enables extensive logging. Useful for troubleshooting.
          - -report-ingress-status
          - -external-service=nginx-ingress
         #- -enable-prometheus-metrics
         #- -global-configuration=$(POD_NAMESPACE)/nginx-configuration
</code></pre>
<p>Ingress controller service yaml</p>
<pre><code>apiVersion: v1
kind: Service
metadata:
  name: nginx-ingress
  namespace: nginx-ingress
spec:
  externalTrafficPolicy: Local
  type: LoadBalancer
  ports:
  - port: 3000
    targetPort: 80
    protocol: TCP
    name: http
  - port: 443
    targetPort: 443
    protocol: TCP
    name: https
  selector:
    app: nginx-ingress
</code></pre>

<p><strong>TL;DR</strong></p>
<p>Switch your <code>pathType</code> in both <code>/api</code> and <code>/</code> path to <strong><code>Prefix</code></strong>.</p>
<p>I've included some explanation with fixed <code>Ingress</code> resource below.</p>
<hr />
<p>For the reproduction purposes I used the <code>titanic</code> manifests that you provided in the another question:</p>
<ul>
<li><em><a href="https://github.com/strobosco/titanicfullstack" rel="nofollow noreferrer">Github.com: Strobosco: Titanicfullstack</a></em></li>
</ul>
<p>The issue with your configuration is with: <code>pathType</code>.</p>
<p>Using your <code>Ingress</code> resource with <code>pathType: Exact</code> showed me blank page.</p>
<p>Modifying your <code>Ingress</code> resource with <code>pathType: Prefix</code> solved the issue.</p>
<blockquote>
<p>Side note!</p>
<p>The message: <strong>&quot;Would you have survived the sinking of the Titanic?&quot;</strong> showed.</p>
</blockquote>
<p>The exact <code>Ingress</code> configuration should be following:</p>
<pre><code>apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: titanic-ingress
spec:
  ingressClassName: nginx
  rules:
  - host: localhost
    http:
      paths:
      - path: /
        pathType: Prefix # &lt;-- IMPORTANT
        backend:
          service:
            name: titanicfrontendservice
            port:
              number: 3000
      - path: /api
        pathType: Prefix # &lt;-- IMPORTANT
        backend:
          service:
            name: titanicbackendservice
            port:
              number: 8080
</code></pre>
<hr />
<h3>Why I think it happened?</h3>
<p>Citing the official documentation:</p>
<blockquote>
<h3>Path types</h3>
<p>Each path in an Ingress is required to have a corresponding path type. Paths that do not include an explicit pathType will fail validation. There are three supported path types:</p>
<ul>
<li><p><code>ImplementationSpecific</code>: With this path type, matching is up to the IngressClass. Implementations can treat this as a separate pathType or treat it identically to Prefix or Exact path types.</p>
</li>
<li><p><code>Exact</code>: Matches the URL path exactly and with case sensitivity.</p>
</li>
<li><p><code>Prefix</code>: Matches based on a URL path prefix split by /. Matching is case sensitive and done on a path element by element basis. A path element refers to the list of labels in the path split by the / separator. A request is a match for path p if every p is an element-wise prefix of p of the request path.</p>
</li>
</ul>
<p>-- <em><a href="https://kubernetes.io/docs/concepts/services-networking/ingress/#path-types" rel="nofollow noreferrer">Kubernetes.io: Docs: Concepts: Services networking: Ingress: Path types</a></em> (there are some examples on how the path matching is handled)</p>
</blockquote>
<p><code>Ingress controller</code> is forced to match <strong>only</strong> the <code>/</code> path leaving rest of the dependencies (apart from the <code>index.html</code>) on other paths like <code>/super.jpg</code> and <code>/folder/awesome.jpg</code> to error with <code>404</code> code.</p>
<blockquote>
<p>Side note!</p>
<p>You can test yourself this behavior by spawning an nginx <code>Pod</code> and placing example files in it. After applying the <code>Ingress</code> resource with <code>/</code> and <code>pathType: Exact</code> you won't be able to request it through the <code>Ingress</code> controller but you could access them within the cluster.</p>
</blockquote>
<hr />
<p>I encourage you to check the additional resources:</p>
<ul>
<li><em><a href="https://kubernetes.io/docs/concepts/services-networking/ingress/" rel="nofollow noreferrer">Kubernetes.io: Docs: Concepts: Services networking: Ingress</a></em></li>
<li><em><a href="https://kubernetes.github.io/ingress-nginx/user-guide/ingress-path-matching/" rel="nofollow noreferrer">Kubernetes.github.io: Ingress nginx: User guide: Ingress path matching</a></em></li>
</ul>
