I have a problem with a simple react app that was created using npx create-react-app react-app
. Once deployed on k8s, I got this:
Uncaught SyntaxError: Unexpected token '<'
However, if I would to kubectl port-forward
to the pod and view the app at localhost:3000 (container's pod is at 3000, cluster ip service listening on 3000 and forwarding to 3000) no problem at all.
The ingress routing looks to be fine as I can get to other services to work within the cluster but not to the app. Some help would be greatly appreciated.
Deployment yaml:
apiVersion: apps/v1
kind: Deployment
metadata:
name: react-app-deployment
# namespace: gitlab-managed-apps
spec:
replicas: 1
selector:
matchLabels:
component: react-app
template:
metadata:
labels:
component: react-app
spec:
imagePullSecrets:
- name: simpleweb-token-namespace
containers:
- name: react-app
image: registry.gitlab.com/mttlong/sample/react-app
env:
- name: "PORT"
value: "3000"
ports:
- containerPort: 3000
Cluster ip service:
apiVersion: v1
kind: Service
metadata:
name: react-app-cluster-ip-service
spec:
type: ClusterIP
selector:
component: react-app
ports:
- port: 3000
targetPort: 3000
Dockerfile:
FROM node:10.15.3-alpine as builder
WORKDIR '/app'
COPY ./package.json ./
RUN npm install
COPY . .
RUN npm run build
FROM nginx
EXPOSE 3000
COPY ./nginx/default.conf /etc/nginx/conf.d/default.conf
COPY --from=builder /app/build /usr/share/nginx/html
Ingress Service:
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: orion-ingress-service
annotations:
kubernetes.io/ingress.class: nginx
nginx.ingress.kubernetes.io/rewrite-target: /$2
spec:
rules:
- host: horizon.zeezum.com
http:
paths:
- path: /
backend:
serviceName: react-app-cluster-ip-service
servicePort: 3000
- path: /api(/|$)(.*)
backend:
serviceName: simple-api-nodeport-service
servicePort: 3050
This is most likely the result of a 404 page or a redirect to a page that serves regular html instead of the expected JavaScript files. (A HTML page starts with <html>
or a <!DOCTYPE...>
therefore the <
as unexpected token)
Make sure that you have correctly build the image and you access the page correctly. You can verify by manually accessing the URL with the browser or look into the network tab of your browser development tools to inspect the response. (I assume that either you have cached the index.html and try to access old assets, check your cache header, or that the paths to not match. In that case inspect your image and access the URLs manually)
I had a similar thing. I got rid of the Ingress altogether, and in my Service yaml file changed my Service to type: Nodeport
and added the fields protocol: TCP
and nodePort: <insert nodeport>
under each port.
I got the values ofthe nodeports by running kubectl expose deployment <insert deployment name> --type=NodePort --name=example-service
. Which creates a service and assigns the ports. You can then run kubectl describe services example-service
to display all the nodeport values. You can then copy the values to your Service yaml file.
When its all running you would access the website from the browser using the nodeport that was generated, ie localhost:31077
for example, and not the actual port 3000
.
I then changed any url routes I had to use the nodeport instead of the actual ports and boom.