goTemp

Lint

goTemp is a full stack Golang microservices sample application built using go-micro. The application is built as a series of services that provide:

In its current incarnation (this is wip), this mono-repo uses the following stack as backend:

In terms of the web front end, the stack is as follows:

As far as observability, the application uses:

Finally, for orchestration, the stack is as follows:

Below is a diagram that displays the overall setup of the application:

Diagram showing goTemp components

In a nutshell. the application functionality is as follows in the backend:

Note on running the application natively:

go-Micro uses mdns for service discovery when running locally. While this works really well, mdns is not available by default in all operating systems. As such, the easiest way to run a go-Micro based applications is using Docker or Kubernetes.

Starting the application

goTemp landing page

Before running the application the first time:

    npm install

To start the application:

   make start

Depending on whether you have run the application before, docker may have to download all the dependent images (PostgreSql, TimescaleDB, Nodejs, etc). This may take a while depending on your internet connection speed. Once everything has been downloaded and started, you should see a message in the terminal indicating that the application is listening at localhost:3000. At that point, you can open your browser and navigate to:

    http://localhost:3000

Additionally, observability tooling can be accessed at the addresses below

    Prometheus:  http://localhost:9090
    Grafana:     http://localhost:3001

To stop the application:

    make stop

Running the application on Kubernetes (Minikube)

Prerequisites

Minikube

Ensure that Minikube is installed and running.

Ingress

The application front end connects with the API gateway using via a K8s ingress resource. As such, the ingress addon must be enabled in Minikube. To enabled it, run:

    minikube addons enable ingress

Check the ingress is working using the command below. The command's results should include an entry for the ingress.

    kubectl get pods -n kube-system

Building and pushing images (optional)

Out of the box, the Kubernetes manifest will pull existing Bolbeck goTemp images from Docker Hub. You are welcome to change the Kubernetes manifests in the ./cicd/K8s folder to pull your own images. To build your own images of each service and push them to docker hub run the command below for each of the services:

    make hubpush SERVICE=<serivceName> FOLDER=<folderName>

where serviceName is the name of the service for which the image should be built folderName is the folder that contains the docker file used to build the service image

Example:

     make hubpush SERVICE=usersrv FOLDER=./user

Note that for the web front end and for Timescale DB the command to be used is slightly different:

     make hubpushcontext SERVICE=<serivceName> FOLDER=<folderName>

Running without Vault

Once the ingress has been enabled, deploy the application to Minikube:

    make startkub

If this is the first time running the application in Minikube, the ingress IP address should be configured. Once the application is deployed, check the address and host assigned to the ingress:

    kubectl get ingress

Note that it takes a couple of minutes for K8s to assign the IP to the ingress. As such wait for that happens before moving ahead.

Grab the address & the host from the result of the command above, and add it to your /etc/hosts file:

    <ipAddress> gotemp.tst

Finally, access app:

    minikube service web

To stop the application:

  make stopkub

Note that if you stop the application, you can restart it by just running:

  make startkub
  minikube service web

Running with Vault integration

Before running the app integrated with Vault, follow the steps in the ./vault/README.md directory to set up and prepare Vault

Once the ingress has been enabled and Vault is ready to go, deploy the application to Minikube:

    make vstartkub

If this is the first time running the application in Minikube, the ingress IP address should be configured. Once the application is deployed, check the address and host assigned to the ingress:

    kubectl get ingress

Note that it takes a couple of minutes for K8s to assign the IP to the ingress. As such wait for that happens before moving ahead.

Grab the address & the host from the result of the command above, and add it to your /etc/hosts file:

    <ipAddress> gotemp.tst

Finally, access app:

    minikube service web

To stop the application:

     make vstopkub

Observability

Observability tools access while the application is running in K8s (with or without Vault):

Repo organization

The project is organized in a way that each folder represents either a service, a database or a shared library package. Currently, we have the following:

Additionally, we have the following files in the root directory as well:

Services

We use go-micro as the main GO microservices framework. Using go-micro simplifies many of the tasks associated with building micro services including (but not limited to):

Organization

Each one of the services has a similar structure:

Building

The different service's images can be built from the root of the repo using the docker build command. For example the user service can be built using:

docker build -t usersrv -f user/Dockerfile .

Note that there is no need to run this if you are using docker-compose as that will build the image automatically

Running individual services

The services are designed to run in containers, and the easiest way to run them is to bring them up using docker-compose: As an example we will run the user service with the commands below in a terminal:

docker-compose up usersrv

This will bring up the user service, the postgreSQL DB and NATS Then to run some data through the service, we can start the user client in a new terminal:

docker-compose up usercli

This will bring up run the client service which will attempt to create,update and delete a user. The results will be printed in the console. The server user service will update the DB as necessary and send the updated information to the broker (NATS) so that the audit service may eventually store it in the time series DB. The audit service can be started using:

docker-compose up auditsrv

Databases Initialization

The project initializes each of the DBs and seeds them with tables and data. Data changes made at run time are automatically persisted using mounted volumes when running via docker-compose. See the folders for each DB for details as well as the docker-compose file.

Web front end

Our web front end is built with Svelte and Sapper which have some interesting benefits:

Organization

The web application lives in the ./web folder. Since Sapper and Svelte generate multiple files and folders, we will just discuss the relevant folders below:

Routes

All of our main routes are pretty standard in terms of organization. We will use the customer route (./web/sapper/src/routes/customer) as an example:

There are three routes that do not share the structure above as they have very little functionality and thus are server by a single index.svelte component: root, register and login.

Kubernetes

The application configuration in K8s can be seen in the diagram below. Note that the diagram shows just one of the different microservices and its associated database. The configuration for all other microservices, beyond the shared ingress and API Gateway, is similar to the one depicted in the diagram.

Diagram showing goTemp components

Notes:

Organization

The K8s files live in the ./cicd/K8s folder, and it is organized as follows:

Note that within each of the folders, most related manifests are organized using a prefix. For example, all the front end related services start with the 'web' prefix.

Additional information:

Additional information can be found in the individual folders either in a readme.md or a doc.go file. Additionally, the Makefile contains many command samples that can be used for development.