In a project that I am currently working I am facing a lot of issues related to routing. I think it is a configuration issue and anyone having similar experience can share his experiences..
The Code repository and the build process is in Azure Git Repo
Project builds and runs perfectly on the local machine.
simple angular project with plain vanilla Angular Bootstrap
structure
Devops/
src/
index.html
app/
app-routing.module.ts
app.component.ts
app.component.html
home/
home.component.html
home.component.ts
dashboard/
dashboard.component.html
dashboard.component.ts
In the app-routing.module.ts all the routes are set up where all the paths are mapped to respective components. Also, the default is set to the Home component.
As per standard setup, the index.html has the following tag and value defined by default<base href="/">
During the build process, The namespace and the app name is stored in a environment variable (ENVVALUES).
In kubernetes, lets say, the domain is www.xcompany.com, my namespace is MaxxD and the Deployed app is Devops, then the uri to the hosted site will be www.xcompany.com/maxxd/devops. It is configured that way. Also, as per the Kubernetes standards, a health check webpage should also be present to determine the availability and health of the pod. The path to the health page is: www.xcompany.com/maxxd/devops/api/health
The nginx related settings are stored in a configuration file called default.conf Following are the contents:
server {
listen 80;
server_name localhost;
location ${ENVVALUES}/ {
alias /usr/share/nginx/html/;
index index.html index.htm;
#try_files $uri $uri/ index.html
}
location /api/health/ {
alias /usr/share/nginx/html/health/;
index health.html;
}
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root /usr/share/nginx/html;
}
}
As we can see the default domain name is appended with the ENVVALUES, which contains the information of the namespace and the App Name ("MaxxD/Devops")
The Docker Build is a multi-stage one, comprising of 2 steps.
In the second step, then the Dist files are moved to a nginx image where the nginx conf file is modified and then started.
Following is the content of the DockerFile:
### STAGE 1: Build ###
# We label our stage as ‘builder’
FROM node as builder
# Create the working folder
RUN mkdir -p /usr/src/app
# We define our current path inside of the container
WORKDIR /usr/src/app
# We copy both the package.json and the package.lock.json into the image
COPY package*.json /usr/src/app/
# run npm install to install Angular CLI
RUN npm install @angular/cli -g
# run npm install to install all dependencies of the project
RUN npm ci
# copy all file from repo to build machine
COPY . /usr/src/app/
## Build the angular app in production mode and store the artifacts in dist folder
RUN ng build --prod
### STAGE 2: Setup ###
FROM nginx
# Expose the port 80 of the running container
EXPOSE 80
## Copy our default nginx config
COPY conf/default.conf /etc/nginx/conf.d/
## Remove default nginx website
RUN rm -rf /usr/share/nginx/html/*
## From ‘builder’ stage copy over the artifacts in dist folder to default nginx public folder
COPY --from=builder /usr/src/app/dist/devops /usr/share/nginx/html
## From ‘builder’ stage copy over the artifacts in dist folder to default nginx public folder
COPY --from=builder /usr/src/app/health /usr/share/nginx/html/health
CMD /bin/bash -c "envsubst < /etc/nginx/conf.d/default.conf > /etc/nginx/conf.d/default.conf && exec nginx -g 'daemon off;'"
In the last step the nginx conf file is modified and the ENVVALUES is transposed with the "{namespace/AppName}" value.
After the deployment to the kubernetes cluster we saw that the index.html was loading but with a blank screen. On the chrome debug window we saw the supporting files like .css, .js and images were all throwing 404s even though the home pae was showing the correct uri.
After losing considerable time in trouble shooting, we figured that it was a routing issue which needed the base href to be set with "./" instead of the default value of "/".
The site became available after this and all the components were navigable.
We had to secure the site from unauthorized access and we used the Okta Authorization components for that.
All the required dependencies for Okta were installed and and the configurations completed.
When running locally we found that after a successful authentication, the redirection was not working properly. The implicit/callback which is mapped to a "OktaCallbackComponent" was not getting peroperly loaded.
It was showing an error and it was related to the value set in the base href tag again.
We changed it back to "/" and the full flow of the Authntication and the redirection to the secured sections were working absolutely fine.
But now after a new deployment, the site was again throwing up the same routing related issues.
So the way it stands, if we set the Base href value to "/", then the site works fine locally but not in Kubernetes.
But, if set with "./", it loads the unsecured files locally, doesnt load the secured ones (due to the Okta implicit/callback component as discussed above) where as in Kubernetes, it loads the unsecured files but as like the local instance, after the successful authentication, the redirection of Okta implcit/callback does not work successfully.
I know it has to do with nginx routing and how the server handles the urls and loads the appropriate sections.
My primary line of resolution is to find a way to run the website with the base href set to the default value ("/")
Another Observation: Even when the routing seems to be working, it is navigable only through the root. That is "www.xcompany.com/MaxxD/DevOps/" whic automatically redirects to the "www.xcompany.com/MaxxD/DevOps/home" based on the route rules defined. But if I put "www.xcompany.com/MaxxD/DevOps/home" directly on the address bar then I get a 404..
Any help is much appreciated