Introduction

This document is a guide for my learning to deploy an Angular app connecting to a set of .NET core microservices for authentication and other services. The code repository is here if you want to have a look.

Note: This guide & the above repository will be updated incrementally as and when I come cross new findings or need to make the information accurate.

Prologue

If knowledge = money, I belong to the middle class, this guide is to be a mirror for my own progress toward digital transformation and sharing it, so others can become my friends.

Flashback

I ended up using k8s after trying different platforms and tried to build a local environment for delivering my ideas in no time. While attempting it on my laptop running Windows 10 with 8GB RAM and reasonable HDD space I installed VirtualBox and Vagrant following the Just me and Opensource channel.

Present

I was so excited to learn all the tools that could be tried out in Kubernetes like Istio, Traefik etc. All of a sudden the system I was running locally started to slow down as I played around with it. Researching, I came to know about k3s and k3d from this video by Darren at Rancher Labs. The Civo service with k3s is mind blowing to me: I don't have to take care of the infrastructure complexity anymore and can concentrate on the applications.

Following the learning guide here, I have done some experiments in Civo: I have installed a docker, dotnet core web API using faas cli Docker image, and am also trying to push a full-stack app using Angular + .NET core + MongoDB + Identity Server 4. I am a web application developer trying to be a data scientist by 2025. I don't know whether its ambitious but I want to try. On its way, trying to experiment and create an eco system in Civo with all the tools for my ideas - having microservices, web apps, machine learning models. I hope one day I will be proud to run a production ready idea that has revolutionized the world :-). I will create a series of blog post having most of the commands into and mention whether its failure or success.

Design

The application we are deploying consists of the following, and is illustrated in the design image below:

  1. .Net Core
  2. Angular
  3. MongoDB
  4. Python
  5. Java Spring Boot

Conceptual Diagram

Prerequisites

  1. Use WSL in windows
  2. Install Docker, Windows Terminal
  3. Use VS Code with Dotnet Core and Angular framework essentials
  4. Where you see "TAG" below in commands, replace it with your Docker ID.
  5. Where you see "PROJECT" below in commands, replace with your Project Name

I followed the instructions here, following are the commands used:

First, the WSL2 install & update:

dism.exe /online /enable-feature /featurename:Microsoft-Windows-Subsystem-Linux /all /norestart
dism.exe /online /enable-feature /featurename:VirtualMachinePlatform /all /norestart

Then, install docker desktop and enable WSL:

NOTE: I am doing the export import because there was no enough space in my default WSL drive

wsl --list -v
wsl --export docker-desktop-data "K:\Kubernetes\ubuntu-wsl\Docker\wsl\docker-desktop-data.tar"
wsl --unregister docker-desktop-data
wsl --import docker-desktop-data "K:\Kubernetes\ubuntu-wsl\Docker\wsl\data" "K:\Kubernetes\ubuntu-wsl\Docker\wsl\docker-desktop-data.tar" --version 2

NOTE: Don’t forget to change the local path “K:\Kubernetes\ubuntu-wsl\Docker\wsl\data” to correspond to your local path as it may be different.

Finally, in your Docker Desktop settings, make sure to enable “use the WSL 2 based engine”:

Windows Docker Desktop Settings

Civo Setup

civo kubernetes ls
civo kubernetes config "PROJECT" --save --merge

kubectl config get-contexts
kubectl config set-context "PROJECT"
kubectl config use-context "PROJECT"

Development

  • VS Code
    1. task.json - setup the tasks for local integrated environment
    2. launch.json - to run the entire project locally as an integrated project
  • Dotnet Core
    1. Create a web api project for book service
    2. Create another for chapter service

Setup identity server

I have followed this blog here to setup MongoDB as backend for identity server, there were some updates required besides the blog. These were the commands required:

>npm i oidc-client
>ng new angular-client
>dotnet new webapi
>dotnet new -i IdentityServer4.Templates
>mkdir PROJECT-idserver
>cd .\ PROJECT-idserver\
>dotnet new is4ef
>dotnet new is4inmem

Dockerization

Running MongoDB Locally

Replace the path and "PROJECT" below with your path and project name:

docker run --rm -d -p 27017:27017 -v /civolab/lab/"PROJECT":/data/db mongo

Managing Secrets

kubectl delete secret secret-idserver-appsettings -n openfaas-fn
kubectl create secret generic secret-idserver-appsettings --from-file=secret-appsettings=appsettings.secrets.json -n openfaas-fn

Deployment

As mentioned above, make sure that "PROJECT" and "TAG" below are changed to be your project name and Docker ID respectively in the following snippets:

Docker Build

docker build . -f Dockerfile -t PROJECT-web:local
docker tag "PROJECT"-web:local <tag>/ "PROJECT"-web:v.0.2
docker push <TAG>/ PROJECT-web:v.0.2

OpenFaaS Setup & Deploy


curl -sLSf https://cli.openfaas.com | sudo sh
export OPENFAAS_PREFIX="<tag>/"
export DNS="<YOUR_CIVO_CLUSTER_ID>.k8s.civo.com" # As per dashboard
export OPENFAAS_URL=http://$DNS:31112
PASSWORD=$(kubectl get secret -n openfaas basic-auth -o jsonpath="{.data.basic-auth-password}" | base64 --decode; echo)
echo -n $PASSWORD | faas-cli login --username admin --password-stdin

faas-cli new --lang dockerfile api
faas-cli build
faas-cli push -f stack.yml # Contains all the image deployment
faas-cli deploy -f stack.idserver.yml # individual deployment
faas-cli deploy -f stack.web.yml

Helm Install

I have used the helm installation for identity server 4 dotnet microservice because the OpenFaaS url was noat idel to resolve the host path. If we install it using helm we can setup the ingress.

helm upgrade --install "PROJECT"-frontend /"PROJECT"-web/conf/charts/"PROJECT"-ui --namespace PROJECT --set app.image=<TAG>/"PROJECT"-web:latest
helm uninstall "PROJECT"-frontend -n "PROJECT"

Testing & Monitoring

I followed the monitoring guide here

docker run --rm -p 5000:8080 -ti  -e ASPNETCORE_ENVIRONMENT=Development "PROJECT"-idserver:local

kubectl get all -o wide -n "PROJECT"
kubectl get all -o wide -n openfaas-fn

kubectl port-forward svc/prometheus-operator-grafana 8080:80  -n monitoring
kubectl port-forward svc/prometheus-operator-operator 8082:8080 -n monitoring
kubectl port-forward svc/prometheus-operator-alertmanager 9093 -n monitoring

Get into the pod running in the cluster and verify the files:

kubectl exec --stdin --tty <podname> -n openfaas-fn -- sh

Conclusion

Deploying an application into the cloud has not been without its challenges. In no particular order, here are some things that I have learned through the process:

  1. Setting up a local system and its limitations (8GB RAM)
  2. Dotnet Core
  3. Angular Error: because its MIME type ('text/plain') is not a supported stylesheet MIME type, and strict MIME checking is enabled. Strict MIME checking
    • I resolved it by adding base href="/function/"PROJECT"-web.openfaas-fn/" in index.html
  4. IdentityServer setup
    • Q: I am trying to deploy a dotnet core identityserver4 into my cluster using OpenFaaS. When my angular client hit the pod for authentication the url resolves to mysever.openfass-fn.svc.cluster.local:8080 instead of the external url. Any idea?
    • A: I fixed it by hosting it separately using helm and configured traefik ingress.
    • Q: Unable to connect to MongoDB in the Civo cluster from compass?
    • A: Open firewall to port 27017
  5. Microservice Architecture
  6. Ployglot implementation

If you would like to let me know you have followed along with this guide, you can reach out to me on Twitter at RRaajjesshh or in the Civo Community Slack.