Make Angular app available via Kubernetes

7/7/2020

I create a Docker image of an Angular app.

Dockerfile:

FROM node:alpine AS builder

WORKDIR /app

COPY . .

RUN npm install
RUN npm run build-prod

FROM nginx:alpine

COPY --from=builder /app/dist/* /usr/share/nginx/html/

build-prod will execute ng build --prod=true

This image is then pushed to a repository and used in a service in a Kubernetes cluster.

apiVersion: apps/v1
kind: Deployment
metadata:
  name: web-client-deployment
  labels:
    app: webclient
spec:
  replicas: 1
  selector:
    matchLabels:
        app: webclient
  template:
    metadata:
      labels:
        app: webclient
    spec:
      imagePullSecrets:
        - name: "azurecr-xxx"
      containers:
      - name: webclient
        image: xxx.azurecr.io/webclient:dev
        imagePullPolicy: Always
        ports:
        - containerPort: 80
---
apiVersion: v1
kind: Service
metadata:
  name: webclient
spec:
  type: ClusterIP
  ports:
  - port: 80
  selector:
    app: webclient

Which is made available via an Ingress Controller.

apiVersion: cert-manager.io/v1alpha2
kind: ClusterIssuer
metadata:
  name: letsencrypt
spec:
  acme:
    server: https://acme-v02.api.letsencrypt.org/directory
    email: xxx@xxx.xxx
    privateKeySecretRef:
      name: letsencrypt
    solvers:
      - http01:
          ingress:
            class: nginx
apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
  name: app-ingress
  annotations:
    kubernetes.io/ingress.class: nginx
    cert-manager.io/cluster-issuer: letsencrypt
    nginx.ingress.kubernetes.io/rewrite-target: /$1
spec:
  tls:
    - hosts:
      - app.xxx.dev
      secretName: app-tls-secret
  rules:
    - host: app.xxx.dev
      http:
        paths:
          - path: /?(.*)
            backend:
              serviceName: webclient
              servicePort: 80

The problem I am having is that I can reach the Angular app (index.html, main.js, polyfills.js, etc.) via the app.xxx.dev web address, but the Angular app cannot load additional static files (eg. images under assets/images). It will get an 404.

What do I do wrong? How do I reach the static files of my Angular app?

-- Palmi
angular
kubernetes
kubernetes-ingress

1 Answer

7/7/2020

I made two mistakes: 1. The asterisk in the COPY command in the Dockerfile messed up the folder structure in the container. Correct is COPY --from=builder /app/dist/ /usr/share/nginx/html/ 2. I need to add the outputPath folder from the angular.json file to the rewrite-target annotation. Correct is nginx.ingress.kubernetes.io/rewrite-target: /app-spa/$1

-- Palmi
Source: StackOverflow