<p>I am new to Kubernetes and this is my first time deploying a react-django web app to Kubernetes cluster.</p>
<p>I have created:</p>
<ol>
<li>frontend.yaml # to run npm server</li>
<li>backend.yaml # to run django server</li>
<li>backend-service.yaml # to make django server accessible for react.</li>
</ol>
<p>In my frontend.yaml file I am passing <code>REACT_APP_HOST</code> and <code>REACT_APP_PORT</code> as a env variable and changed URLs in my react app to:</p>
<pre><code>axios.get('http://'+`${process.env.REACT_APP_HOST}`+':'+`${process.env.REACT_APP_PORT}`+'/todolist/api/bucket/').then(res =&gt; {
      setBuckets(res.data);
      setReload(false);
    }).catch(err =&gt; {
      console.log(err);
    })
</code></pre>
<p>and my URL becomes <code>http://backend-service:8000/todolist/api/bucket/</code></p>
<p>here <code>backend-service</code> is name of backend-service that I am passing using env variable <code>REACT_APP_HOST</code>.</p>
<p>I am not getting any errors, but when I used <code>kubectl port-forward &lt;frontend-pod-name&gt; 3000:3000</code> and accessed <code>localhost:3000</code> I saw my react app page but it did not hit any django apis.</p>
<p>On chrome, I am getting error:</p>
<pre><code>net::ERR_NAME_NOT_RESOLVED
</code></pre>
<p>and in Mozilla:</p>
<pre><code>Cross-Origin Request Blocked: The Same Origin Policy disallows reading the remote resource at http://backend-service:8000/todolist/api/bucket/. (Reason: CORS request did not succeed).
</code></pre>
<p>Please help on this issue, I have spent 3 days but not getting any ideas.</p>
<p><strong>frontend.yaml</strong></p>
<pre><code>apiVersion: apps/v1
kind: Deployment
metadata:
  creationTimestamp: null
  labels:
    app: frontend
  name: frontend
spec:
  replicas: 1
  selector:
    matchLabels:
      app: frontend
  strategy: {}
  template:
    metadata:
      creationTimestamp: null
      labels:
        app: frontend
    spec:
      containers:
      - image: 1234567890/todolist:frontend-v13
        name: react-todolist
        env:
          - name: REACT_APP_HOST
            value: &quot;backend-service&quot;
          - name: REACT_APP_PORT
            value: &quot;8000&quot;
        ports:
          - containerPort: 3000
        volumeMounts:
          - mountPath: /var/log/
            name: frontend
        command: [&quot;/bin/sh&quot;, &quot;-c&quot;]
        args:
          - npm start;
      volumes:
        - name: frontend
          hostPath:
            path: /var/log/
</code></pre>
<p><strong>backend.yaml</strong></p>
<pre><code>apiVersion: apps/v1
kind: Deployment
metadata:
  creationTimestamp: null
  labels:
    app: backend
  name: backend
spec:
  replicas: 1
  selector:
    matchLabels:
      app: backend
  template:
    metadata:
      creationTimestamp: null
      labels:
        app: backend
    spec:
      serviceAccountName: backend-sva
      containers:
      - image: 1234567890/todolist:backend-v11
        name: todolist
        env:
          - name: DB_NAME
            value: &quot;todolist&quot;
          - name: MYSQL_HOST
            value: &quot;mysql-service&quot;
          - name: MYSQL_USER
            value: &quot;root&quot;
          - name: MYSQL_PORT
            value: &quot;3306&quot;
          - name: MYSQL_PASSWORD
            value: &quot;mysql123&quot;
        ports:
          - containerPort: 8000
        volumeMounts:
          - mountPath: /var/log/
            name: backend
        command: [&quot;/bin/sh&quot;, &quot;-c&quot;]
        args:
          - apt-get update;
            apt-get -y install vim;
            python manage.py makemigrations bucket;
            python manage.py migrate;
            python manage.py runserver 0.0.0.0:8000
      volumes:
        - name: backend
          hostPath:
            path: /var/log/
</code></pre>
<p><strong>backend-service.yaml</strong></p>
<pre><code>apiVersion: v1
kind: Service
metadata:
  creationTimestamp: null
  labels:
    app: backend
  name: backend-service
spec:
  ports:
  - port: 8000
    targetPort: 8000
  selector:
    app: backend
status:
  loadBalancer: {}
</code></pre>
<p><strong>frontend docker file</strong></p>
<pre><code>FROM node:14.16.1-alpine

COPY package.json /app/react-todolist/react-todolist/
WORKDIR /app/react-todolist/react-todolist/

RUN npm install

COPY . /app/react-todolist/react-todolist/

EXPOSE 3000
</code></pre>
<p><strong>backend docker file</strong></p>
<pre><code>FROM python:3.6

COPY requirements.txt ./app/todolist/
WORKDIR /app/todolist/

RUN pip install -r requirements.txt

COPY . /app/todolist/
</code></pre>
<p><strong>django settings</strong></p>
<pre><code>CORS_ORIGIN_ALLOW_ALL=True

# Application definition

INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',

    # Rest Frame Work
    'rest_framework',
    # CORS
    'corsheaders',

    # Apps
    'bucket',
]

MIDDLEWARE = [
    'corsheaders.middleware.CorsMiddleware',
    'django.middleware.security.SecurityMiddleware',
    'django.contrib.sessions.middleware.SessionMiddleware',
    'django.middleware.common.CommonMiddleware',
    'django.middleware.csrf.CsrfViewMiddleware',
    'django.contrib.auth.middleware.AuthenticationMiddleware',
    'django.contrib.messages.middleware.MessageMiddleware',
    'django.middleware.clickjacking.XFrameOptionsMiddleware',
]
</code></pre>
<p><strong>ingress.yaml</strong></p>
<pre><code>apiVersion: extensions/v1beta1

kind: Ingress

metadata:
  name: todolist-ingress

spec:
  rules:
    - host: kubernetes.docker.internal
      http:
       paths:
        - path: /
          backend:
            serviceName: frontend-service
            servicePort: 3000
        
        - path: /
          backend:
            serviceName: backend-service
            servicePort: 8000
  
</code></pre>
<p><strong>react axios api</strong></p>
<pre><code>useEffect(() =&gt; {
    axios.get('http://'+`${process.env.REACT_APP_HOST}`+':'+`${process.env.REACT_APP_PORT}`+'/todolist/api/bucket/', {
      headers: {&quot;Access-Control-Allow-Origin&quot;: &quot;*&quot;}
    }).then(res =&gt; {
      setBuckets(res.data);
      setReload(false);
    }).catch(err =&gt; {
      console.log(err);
    })
  }, [reload])
</code></pre>
<p><strong>web app github link</strong> <a href="https://github.com/vgautam99/ToDoList" rel="nofollow noreferrer">https://github.com/vgautam99/ToDoList</a></p>

Vikas Gautam
<p>Welcome to the community!</p>
<p>I reproduced your example and made it work fine.
I forked your repository, made some changes to js files and package.json and added Dockerfiles (you can see this commit <a href="https://github.com/fivecatscats/ToDoList/commit/74790836659232284832688beb2e1779660d7615" rel="nofollow noreferrer">here</a></p>
<p>Since I didn't change database settings in <code>settings.py</code> I attached it as a <code>configMap</code> to backend deployment (see <a href="https://github.com/fivecatscats/ToDoList/blob/master/backend-deploy.yaml#L37-L39" rel="nofollow noreferrer">here</a> how it's done). Config map was created by this command:</p>
<p><code>kubectl create cm django1 --from-file=settings.py</code></p>
<p>The trickiest part here is to use your domain name <code>kubernetes.docker.internal</code> and add your port with <code>/backend</code> path to environment variables you're passing to your frontend application (see <a href="https://github.com/fivecatscats/ToDoList/blob/master/frontend-deploy.yaml#L21-L24" rel="nofollow noreferrer">here</a>)</p>
<p>Once this is done, it's time to set up an ingress controller (this one uses apiVersion - <code>extestions/v1beta1</code> as it's done in your example, however it'll be deprecated soon, so it's advised to use <code>networking.k8s.io/v1</code> - example  of a newer apiVersion is <a href="https://github.com/fivecatscats/ToDoList/blob/master/ingress-after-1-22.yaml" rel="nofollow noreferrer">here</a>):</p>
<pre><code>apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: todolist-backend-ingress
  annotations:
    nginx.ingress.kubernetes.io/rewrite-target: /$2
    nginx.ingress.kubernetes.io/use-regex: &quot;true&quot;
spec:
  rules:
    - host: kubernetes.docker.internal
      http:
       paths:
        - path: /backend(/|$)(.*)
          backend:
            serviceName: backend-service
            servicePort: 8000
---
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: todolist-frontend-ingress
  annotations:
spec:
  rules:
    - host: kubernetes.docker.internal
      http:
       paths:
        - path: /
          backend:
            serviceName: frontend-service
            servicePort: 3000
</code></pre>
<p>I set it up in two different ingresses because there are some issues with <code>rewrite-target</code> and <code>regex</code> using root path <code>/</code>. As you can see we use <code>rewrite-target</code> here because requests are supposed to hit <code>/todolist/api/bucket</code> path instead of <code>/backend/todolist/api/bucket</code> path.
Please see <a href="https://kubernetes.github.io/ingress-nginx/examples/rewrite/" rel="nofollow noreferrer">nginx rewrite annotations</a></p>
<p>Next step is to find an IP address to test your application from the node where kubernetes is running and from the web.
To find IP addresses and ports run <code>kubectl get svc</code> and <code>find ingress-nginx-controller</code>:</p>
<pre><code>NAME                                 TYPE           CLUSTER-IP       EXTERNAL-IP     PORT(S)                      AGE
backend-service                      ClusterIP      10.100.242.79    &lt;none&gt;          8000/TCP                     21h
frontend-service                     ClusterIP      10.110.102.96    &lt;none&gt;          3000/TCP                     21h
ingress-nginx-controller             LoadBalancer   10.107.31.20     192.168.1.240   80:31323/TCP,443:32541/TCP   8d
</code></pre>
<p>There are two options: <code>CLUSTER-IP</code> and <code>EXTERNAL-IP</code> if you have loadbalancer set up.
On your kubernetes  control plane, you can run a simple checking test with <code>curl</code> command using <code>CLUSTER-IP</code> address. In my case it looks like:</p>
<p><code>curl http://kubernetes.docker.internal/ --resolve kubernetes.docker.internal:80:10.107.31.20</code></p>
<p>And next test is:</p>
<p><code>curl -I http://kubernetes.docker.internal/backend/todolist/api/bucket --resolve kubernetes.docker.internal:80:10.107.31.20</code></p>
<p>Output will be like:</p>
<pre><code>HTTP/1.1 301 Moved Permanently
Date: Fri, 14 May 2021 12:21:59 GMT
Content-Type: text/html; charset=utf-8Content-Length: 0
Connection: keep-alive
Location: /todolist/api/bucket/
X-Content-Type-Options: nosniff
Referrer-Policy: same-origin
Vary: Origin
</code></pre>
<p>Next step is access your application via web browser. You'll need to correct <code>/etc/hosts</code> on your local machine (linux/Mac OS, for Windows it's a bit different, but very easy to find) to match <code>kubernetes.docker.internal</code> domain with proper IP address.</p>
<p>If you're using a <code>load balancer</code> then <code>EXTERNAL-IP</code> is the right address.
If you don't have a <code>load balancer</code> then it's possible to reach out to the node directly. You can find IP address in cloud console and add it to <code>/etc/hosts</code>. In this case you will need to use a different port. In my case it was <code>31323</code> (you can find it above in <code>kubectl get svc</code> output).</p>
<p>When it's set up, I hit the application in my web-browser by <code>http://kubernetes.docker.internal:31323</code></p>
<p>(Repository is <a href="https://github.com/fivecatscats/ToDoList" rel="nofollow noreferrer">here</a> feel free to use everything you need from it)</p>
