A fullstack epic part III — using Docker and Kubernetes to ship and scale everything

Shipping, swarming and scaling our dummy app

Mauricio M. Ribeiro
5 min readJan 30, 2017

Introduction

In Part I we developed the backend part of our dummy app, which serves the data to our frontend part developed in Part II.

In this third section of our “fullstack adventure” we are going to ship both parts using Docker; and use Kubernetes in order to manage their deployment.

Note: I’m using Linux during these series. If you want to use Docker/Kubernetes for Windows, don’t hesitate in taking a look here.

Shipping and deploying our extremely simple dummy application

Docker is awesome. It makes extremely simple the headache of configuring environments and making everything ready to deploy our applications. You can download Docker here.

In order to deploy the applications, we are going to use minikube and kubectl. They make it really simple to manage and scaling our applications. Don’t forget to install a VM manager (I strongly recommend Virtual Box, for any environment, even Windows).

So, let’s see how we are going to ship and deploy our REST API and our webpage.

Setup

First of all, we should start Minikube in order to make Kubernetes run in the local machine.

IMPORTANT NOTE: if you are in a Linux environment, make sure you perform ALL the steps from now on as a user with admin permissions.

# With 'v=3' we can see the details of some steps. Its usage is OPTIONAL
$ minikube start --v=3
Starting local Kubernetes cluster...
Running pre-create checks...
Creating machine...
Starting local Kubernetes cluster...

Then, we use the following command in order to make Docker run inside minikube’s environment.

# running Docker inside minikube
$ eval $(minikube docker-env)

Just to be sure, run this command and check that you are inside minikube environment

# here we are going to see a set of images inside minikube
$ docker images

Optional step: I like to organize my deployments into namespaces. However, you should NOT feel obliged to do it. Kubernetes has a ‘default’ namespace to put all of deployments, pods and services inside.

NOTE: If you decide to go for the default namespace, some changes will have to be done in the steps below.

# creating namespace
$ kubectl create namespace musicstore

Now we are ready to move on.

First: the backend part

Create a Dockerfile inside the src/musicstore directory, and paste the contents below:

# pulling a lightweight version of golang (in Alpine Linux)
FROM golang:1.8-alpine
RUN apk --update add --no-cache git
# Copy the local package files to the container's workspace.
ADD . /go/src/musicstore
WORKDIR /go/src/musicstore
# Build the outyet command inside the container.
# (You may fetch or manage dependencies here,
# either manually or with a tool like "godep".)
RUN go get musicstore
# Run the command by default when the container starts.
ENTRYPOINT ["/go/bin/musicstore"]
# Document that the service listens on port 9000.
EXPOSE 9000

I use Alpine Linux in order to build my Docker images whenever possible. It is amazing how images get smaller when building under Alpine. Consider using it if you fear you are going to deploy a lot of different services and don’t want that each one of them gets lots of space.

Now, we build the image:

# building the image
$ docker build -t api-musicstore:v1 .
# check that the image is well built
$ docker images

With the image built, we can use minikube to deploy it. For this, we are going to use these files.

Remove all references to namespace musicstore if you decided to place your deployments under the default namespace.

# create a deployment inside namespace 'musicstore'
$ kubectl create -f deployment.json
# create a replication controller to assure
# that we are always going to have 3 replicas of this deployment
# running at a time
$ kubectl create -f rc.yaml
# then, create a service to export this deployment
$ kubectl create -f service.json
# now, we can see in which URL our backend will be running
$ minikube service api-musicstore --namespace=musicstore --url
http://192.168.99.100:32495

If you browse the URL, you are going to see an empty list of albums. The REST API is running!

Second: the frontend part

Now that we are aware of the URL of our service, we will have to change this value in our album.service.ts file of our Angular solution:

// album-service.service.ts
...
export class AlbumService {
constructor(private http: Http) { }// this is the endpoint of our REST API service in Go
private albumsUrl = 'http://192.168.99.100:32495/';
...
}

Note: we are doing ugly like this because the point here is to keep everything as simple as possible. Of course an environment variable would be far better.

With this done, we have to build a “prod version” of our website. Angular CLI helps us with the command:

# browse the frontend app folder
$ cd <path>/musicstore
# build the prod version
$ ng build --env=prod

This will bundle and minify all the JS and copy the contents inside a dist/ folder. This folder is what is we are going to deploy.

Still in the frontend app root folder, create the Dockerfile and paste these contents into it:

# Builds a Docker to deliver dist/
FROM nginx:1.11.9-alpine
COPY dist/ /usr/share/nginx/html

Again, Alpine Linux. Here we are going to build an nginx image and put the contents of our website there.

Time to deploy. We are going to use this file to create our deployment.

# building the image
$ docker build -t musicstore:v1 .
# check that the image is well built
$ docker images
# create a deployment inside namespace 'musicstore'
$ kubectl create -f deployment.json
# expose it as a service
$ kubectl expose deployment musicstore-website --namespace=musicstore --type=LoadBalancer
# get the service URL (port will not be necessarily 31900)
$ minikube service musicstore-website --namespace=musicstore --url
http://192.168.99.100:31900/

And that’s it! If you browse the URL you will see the page we developed in Part II retrieving and creating music albums using the REST API developed in Part I!

Last but not least: you can manage all the deployments, pods and services in Kubernetes UI:

$ minikube dashboard

What now?

Now that we saw the very basic steps of building the frontend and backend parts of an application, as well as dockerizing and deploying each one of them; it is time to take more advanced steps.

We don’t want to stop in only displaying and creating albums. We also want to update and delete them.

We don’t want our website to look blank either. Some design styling will have to be done.

Also, we don’t want our frontend service setting the backend URL in this non-professional style. This have to be placed in some environment config.

And … what about using Ingress?

During the development of these posts, I have faced some annoying issues. A post with troubleshooting is also expected.

So, lots of work to do! But you see that it is possible to have a close look to each part of an app. We can only focus in one or two things, but it is always good to have a critical vision in as many things as we can.

Useful links

Kubectl Overview

Minikube tutorial

Getting started in Kubernetes on your Windows laptop

Running your own Docker images in Minikube for Windows

Github project with the sources of these series

--

--