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.yamlIssue
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.jsonbasename in the react-router-domNone 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: 3000Repo to demo the issue:
Create React App assumes your application is hosted at the serving web server's root or a subpath as specified in package.json (homepage). Normally, Create React App ignores the hostname. You may use this variable to force assets to be referenced verbatim to the URL you provide (hostname included). This may be particularly useful when using a CDN to host your application.
There are three ways to fix this problem:
{
...
homepage: "/client"
...
}
Reference:
https://create-react-app.dev/docs/advanced-configuration/Apparently, this is not possible currently in CRA in a dev environment:
https://github.com/facebook/create-react-app/issues/8222#issuecomment-568308139