Not sure if this is a Kubernetes, ingress-nginx
, or ReactJS (create-react-app
) issue...
Project Structure
new-app/
client/
src/
App.js
index.js
Test.js
package.json
k8s/
client.yaml
ingress.yaml
server/
skaffold.yaml
Issue
192.168.64.5/client
when the cluster is spun up with Skaffold192.168.64.5/client
and blank screenBasically, it is trying to serve static files from /static
, but I need them to come from /client/static
Propsed Solutions
Assuming this is a ReactJS issue, the solutions have been the following:
homepage
in the package.json
basename
in the react-router-dom
None seem to work in my case. Still shows assets trying to be served from /static
instead of /client/static
.
ReactJS App Code
// App.js
import React from 'react';
import { BrowserRouter, Route } from 'react-router-dom';
import './App.css';
import Test from './Test';
const App = () => {
return (
<BrowserRouter
basename='/client'>
<>
<Route exact path='/' component={Test} />
</>
</BrowserRouter>
);
}
export default App;
// Test.js
import React, { useState, useEffect } from 'react';
import logo from './logo.svg';
import './App.css';
import axios from 'axios';
const Test = () => {
const [data, setData] = useState('');
useEffect(() => {
const fetchData = async () => {
const result = await axios('/api/auth/test/');
setData(result.data);
};
fetchData();
}, []);
return (
<div className='App'>
<header className='App-header'>
<img src={logo} className='App-logo' alt='logo' />
<p>
Edit <code>src/App.js</code> and save to reload!
</p>
<p>
{data}
</p>
<a
className='App-link'
href='https://reactjs.org'
target='_blank'
rel='noopener noreferrer'
>
Learn React
</a>
</header>
</div>
)
};
export default Test;
{
"name": "client",
"version": "0.1.0",
"private": true,
"homepage": "/client",
"dependencies": {
"axios": "^0.19.0",
"react": "^16.12.0",
"react-dom": "^16.12.0",
"react-router-dom": "^5.1.2",
"react-scripts": "3.2.0"
},
"scripts": {
"start": "react-scripts start",
"build": "react-scripts build",
"test": "react-scripts test",
"eject": "react-scripts eject"
},
"eslintConfig": {
"extends": "react-app"
},
"browserslist": {
"production": [
">0.2%",
"not dead",
"not op_mini all"
],
"development": [
"last 1 chrome version",
"last 1 firefox version",
"last 1 safari version"
]
}
}
Kubernetes/Skaffold and Docker Manifests
# Dockerfile.dev
FROM node:alpine
EXPOSE 3000
WORKDIR '/app'
COPY ./client/package.json ./
RUN npm install
COPY ./client .
CMD ["npm", "run", "start"]
# ingress.yaml
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: ingress-service
annotations:
kubernetes.io/ingress.class: nginx
nginx.ingress.kubernetes.io/add-base-url: "true"
nginx.ingress.kubernetes.io/rewrite-target: /$1
spec:
rules:
- http:
paths:
- path: /client/?(.*)
backend:
serviceName: client-cluster-ip-service
servicePort: 3000
# client.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: client-deployment
spec:
replicas: 3
selector:
matchLabels:
component: client
template:
metadata:
labels:
component: client
spec:
containers:
- name: client
image: clientappcontainers.azurecr.io/client
ports:
- containerPort: 3000
---
apiVersion: v1
kind: Service
metadata:
name: client-cluster-ip-service
spec:
type: ClusterIP
selector:
component: client
ports:
- port: 3000
targetPort: 3000
# skaffold.yaml
apiVersion: skaffold/v1beta15
kind: Config
build:
local:
push: false
artifacts:
- image: clientappcontainers.azurecr.io/client
docker:
dockerfile: ./client/Dockerfile.dev
sync:
manual:
- src: "***/*.js"
dest: .
- src: "***/*.html"
dest: .
- src: "***/*.css"
dest: .
deploy:
kubectl:
manifests:
- manifests/ingress.yaml
- manifests/client.yaml
So what am I doing wrong here?
EDIT:
I should note that things work fine when doing this though:
- path: /?(.*)
backend:
serviceName: client-cluster-ip-service
servicePort: 3000
Repo to demo the issue:
Apparently, this is not possible currently in CRA in a dev environment:
https://github.com/facebook/create-react-app/issues/8222#issuecomment-568308139