areller
areller

Reputation: 5238

Angular app on Kubernetes Ingress when using non-root path

I have an Angular app which works perfectly in the development environment.

When I try to deploy it to a Kubernetes cluster and create an ingress route for it, things don't work as expected.

Specifically, I'm using this ingress definition

apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: angular-website
  annotations:
    kubernetes.io/ingress.class: "nginx"
spec:
  rules:
  - http:
      paths:
      - backend:
          serviceName: angular-website
          servicePort: 80
        path: /website(/($|.*))?

When I try to go to that ingress route, I see a blank page and it the network tab (in Chrome), I see these errors

enter image description here

I realize that this is happening because I'm trying to route on a non-root path (i.e. something that isn't /), and Angular isn't "aware" of that and assumes that the app runs from the root path when it tries to load all the JS bundles.

I realize that I can fix this by editing a section in the main index.html in my application from

<base href="/">

to

<base href="/website">

But I rather not do that since it would require me to know the path ahead of time, during build.

Is there a way around it? Is there a way to make Angular dynamically be aware of the root path without having to recompile the app to set that?

Edit

The Angular app is hosted in a NodeJS Express application

const clientPath = path.join(__dirname, "..", "public", "angular-website", "dist", "angular-website");

app.use(express.static(clientPath));
app.get('/*', (req, res) => res.sendFile(path.join(clientPath, "index.html"));

Upvotes: 1

Views: 2008

Answers (1)

areller
areller

Reputation: 5238

I ended up building the Angular app in my Dockerfile like this

RUN npm run build -- --prod --base-href="/{{basePath}}" --deploy-url="{{basePath}}/"

basically, during build, I pass a placeholder to the --base-href and --deploy-url arguments which indicate what's the root path of my app.

Then, when I serve the Angular app from my NodeJS + Express process, I use mustache (a templating engine) to substitute there placeholders with a the root path of my app that's stored in an environment variable.

res.render('index', {
    basePath: process.env.CLIENT_BASE_PATH || ''
});

Upvotes: 2

Related Questions