1
votes

I have a Vue.js application, and my deployment setup is very standard,

Pod -> Service -> Ingress

Here's the related code,

Dockerfile:

FROM node:lts-alpine AS build
WORKDIR /app
COPY . .

# Default build mode
ARG MODE=production

# Build the dist folder
RUN npm ci
RUN npm run build ${MODE}

# Serve from nginx
FROM nginx:alpine
COPY ./nginx.conf /etc/nginx/nginx.conf
COPY --from=build /app/dist /usr/share/nginx/html

Nginx.conf:

user  nginx;
worker_processes  1;
error_log  /var/log/nginx/error.log warn;
pid        /var/run/nginx.pid;
events {
  worker_connections  1024;
}
http {
  include       /etc/nginx/mime.types;
  default_type  application/octet-stream;
  log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
                    '$status $body_bytes_sent "$http_referer" '
                    '"$http_user_agent" "$http_x_forwarded_for"';
  access_log  /var/log/nginx/access.log  main;
  sendfile        on;
  keepalive_timeout  65;
  server {
    listen       8080;
    location / {
      root   /usr/share/nginx/html;
      index  index.html;
      try_files $uri $uri/ /index.html;
    }
  }
}

Ingress Prod: (kept only the necessary bits for brevity sakes),

apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  annotations:
    kubernetes.io/ingress.class: nginx
    nginx.ingress.kubernetes.io/force-ssl-redirect: "true"
    nginx.ingress.kubernetes.io/rewrite-target: /$2
    nginx.ingress.kubernetes.io/ssl-redirect: "true"
  labels:
    app: <my-app>
    app.kubernetes.io/instance: <my-instance>
  name: <my-name>
  namespace: <my-namespace>
spec:
  rules:
    - host: <my-host>
      http:
        paths:
          - backend:
              serviceName: livspace-hub
              servicePort: 80
            path: /

Ingress local:

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: <my-app-name>
  annotations:
    nginx.ingress.kubernetes.io/rewrite-target: /
spec:
  rules:
  - host: <my-host>
    http:
      paths:
      - path: /
        pathType: Prefix
        backend:
          service:
            name: hub-service
            port:
              number: 9090

The error I get is,

Uncaught SyntaxError: Unexpected token '<' chunk-vendors.a727ce10.js:1

Uncaught SyntaxError: Unexpected token '<' app.a68a0468.js:1

And the content-type for both these resources in the network tab is text/html.

Edit 1:

This is what my folder looks like after deployment,

/usr/share/nginx/html # ls
50x.html assets css  favicon.ico fonts index.html  js  styles

The path for my js file is,

https://<my-domain>/js/app.a68a0468.js

Edit 2:

Here are the logs from my local vs deployed application.

Local:

- - [12/Apr/2021:10:38:18 +0000] "GET / HTTP/1.1" 200 3213 "-" "Mozilla/5.0 (Macintosh; Intel Mac OS X 11_2_3) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/89.0.4389.114 Safari/537.36 Edg/89.0.774.75"

- - [12/Apr/2021:10:38:18 +0000] "GET /css/milestone.1c126aff.css HTTP/1.1" 200 1139 "http:///" "Mozilla/5.0 (Macintosh; Intel Mac OS X 11_2_3) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/89.0.4389.114 Safari/537.36 Edg/89.0.774.75"

- - [12/Apr/2021:10:38:18 +0000] "GET /css/catalogue.5794c500.css HTTP/1.1" 200 156 "http:///" "Mozilla/5.0 (Macintosh; Intel Mac OS X 11_2_3) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/89.0.4389.114 Safari/537.36 Edg/89.0.774.75"

Deployed:

- - [12/Apr/2021:12:46:28 +0000] "GET / HTTP/1.1" 200 3213 "https:///" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/89.0.4389.90 Safari/537.36 Edg/89.0.774.54"

- - [12/Apr/2021:12:46:28 +0000] "GET / HTTP/1.1" 200 3213 "https:///" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/89.0.4389.90 Safari/537.36 Edg/89.0.774.54"

- - [12/Apr/2021:12:46:28 +0000] "GET / HTTP/1.1" 200 3213 "https:///" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/89.0.4389.90 Safari/537.36 Edg/89.0.774.54"

- - [12/Apr/2021:12:46:28 +0000] "GET / HTTP/1.1" 200 3213 "https:///" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/89.0.4389.90 Safari/537.36 Edg/89.0.774.54"

My local instance is also run via docker/docker-compose, so the setup is essentially the same.

As you can see, my local setup logs show requests for specific files - GET /<filename> - whereas the deployed instance shows only logs for GET /.

1
It's serving index.html because the file is not found. So the content-type is actually correct for the file it's serving. You need to check the access log and ensure that the file is present in the path /usr/share/nginx/html.Richard Smith
@RichardSmith added some more info to my question.painotpi

1 Answers

1
votes

TL;DR

Remove/Modify the following annotation from Ingress Prod:

  • nginx.ingress.kubernetes.io/rewrite-target: /$2

Explanation:

The annotation that you are using (rewrite-target: /$2) is targeting a capture group that does not exist.

Each request that is sent to your application through your Ingress resource is getting rewritten to /.

To fix that you can either:

  • Entirely remove this annotation.
  • Modify the annotation that would support your rewrite, for example: /.

You can read more about rewrites, capture groups and how nginx-ingress handles them by following this documentation:


Example:

I've used your exact Ingress manifest with slight tweaks and stumbled upon the same issue as you've described:

  • curl IP
  • curl IP/hello.html

To show the request that came to the Pod I've used nginx Pod as a backend:

/docker-entrypoint.sh: Configuration complete; ready for start up
10.88.0.20 - - [13/Apr/2021:15:01:37 +0000] "GET / HTTP/1.1" 200 612 "-" "curl/7.64.1" "SOURCE_IP_OF_MINE"
10.88.0.20 - - [13/Apr/2021:15:01:40 +0000] "GET / HTTP/1.1" 200 612 "-" "curl/7.64.1" "SOURCE_IP_OF_MINE"

Additional resources: