MEAN Applications on Deis Workflow

29 Jun 2016

Deis Workflow is a PaaS that lets you automatically build and deploy applications on a Kubernetes cluster via simple triggers like git push. Workflow also lets you manage app configuration, create or roll back releases, perform extensive logging, and more.

If you are concerned whether Deis Workflow can handle your application, you'll be happy to know there are three ways to deploy:

  1. Heroku buildpacks
  2. Dockerfiles
  3. Docker images

Even if you're not using Heroku buildpacks, you can usually deploy your application via Docker images or Dockerfiles. With all this scope for flexibility, Deis Workflow can cater to almost any cloud software setup.

In this post, we'll get specific though.

Node.js has emerged as one of the most popular server scripting languages. Combined with other modern tools like AngularJS and MongoDB (aka the MEAN stack) it can be a great way for developers to create modern web applications quickly.

So, how do you deploy an Express.js (a web framework based on Node.js) application via Deis Workflow? We'll get to that.

But first, we need to install and launch Deis Workflow.

Install CLI Tools

The Deis CLI tool lets you interact with Deis Workflow. Ideally, you should install the client in your $PATH to avoid any command not found errors.

So, change your directory to /usr/local/bin, and install by running:

$ curl -sSL | bash

Check if it's working with:

$ deis version

Next you'll need to install Helm Classic. Helm is a package manager for Kubernetes. We'll use it to manage software in our Kubernetes cluster.

Install it with:

$ curl -sSL | bash

Again, check if install is successful.

$ helmc --version

Next step is to boot up a Kubernetes cluster.

I have used AWS EC2 as the backend cloud. You can choose to use Google Container Engine (GKE) or even your own laptop.

Since we'll use command line interface to interact with AWS, you'll need to install AWS and Kubernetes CLI tools.

$ curl "" -o ""
$ unzip
$ sudo ./awscli-bundle/install -i /usr/local/aws -b /usr/local/bin/aws
$ curl -O
$ chmod +x kubectl

Once you are done, type:

$ aws configure

You'll be prompted to add the Key ID, Secret Access Key, default region name, and the output format.

You can now interact with your AWS account via the CLI.

Set Up Your Kubernetes Cluster

Create a folder at a suitable place on your computer that will serve as home to your Kubernetes installation.

Then download and unzip Kubernetes:

$ curl -sSL -O
$ tar -xvzf kubernetes.tar.gz
$ cd kubernetes

Now configure the Kubernetes environment:

$ export KUBE_AWS_ZONE=us-west-1c
$ export MASTER_SIZE=t2.medium
$ export NODE_SIZE=t2.large
$ export NUM_NODES=2

Now that you're ready, boot up the cluster using:

$ ./cluster/

Now we have a Kubernetes cluster ready, let's install Deis Workflow.

Install Deis Workflow and Helm

We'll need to use the Helm package manager.

First check if it can connect with your Kubernetes cluster:

$ helmc target

You should get a detailed list like this:

Kubernetes master is running at
Elasticsearch is running at
Heapster is running at
Kibana is running at
KubeDNS is running at
Kubernetes-dashboard is running at
Grafana is running at
InfluxDB is running at

This confirms Helm can talk to your Kubernetes cluster. This is the cluster we booted in the previous section.

The next step is to add Deis charts repo to Helm:

$ helmc repo add deis

Then install Deis Workflow:

$ helmc fetch deis/workflow-rc1
$ helmc generate -x manifests workflow-rc1
$ helmc install workflow-rc1

This will complete the installation process.

You'll have to wait some more for the pods to be ready. You can check the progress using this command:

$ kubectl --namespace=deis get pods

Once all the pods show a ready status, Deis Workflow is up and running.

Here's what that looks like:

$ kubectl —namespace=deis get pods
NAME                  READY     STATUS  RESTARTS    AGE
deis-builder-2sggr    1/1       Running 4           21m
deis-controller-a6fn1 1/1       Running 3           21m
deis-database-blpvp   1/1       Running 0           21m
deis-logger-b42iu     1/1       Running 0           21m
deis-logger-fluentd-1v1/1       Running 0           21m
deis-logger-fluentd-dn1/1       Running 0           21m
deis-minio-ekb42      1/1       Running 0           21m
deis-monitor-grafana-t1/1       Running 0           21m
deis-monitor-influxdb-1/1       Running 0           21m
Deis-monitor-stdout-  1/1       Running 0           21m
deis-monitor-telegraf-1/1       Running 0           21m
deis-monitor-telegraf-1/1       Running 0           21m
deis-registry-c7wo5   1/1       Running 0           21m
deis-router-ygzro     1/1       Running 0           21m
deis-workflow-manager-1/1       Running 0           21m

Deis Workflow on EC2 automatically provisions and attaches an elastic Load balancer (ELB) to the router component.

The router component is responsible for routing HTTP and HTTPS requests from the public internet to your applications in the cluster.

By default, the connection timeout for Elastic Load Balancers is 60 seconds. This is too short for long running connections when using the Deis Workflow git push functionality. So, we'll need to adjust the default load balancer configuration.

First, get the load balancer name by running:

$ kubectl --namespace=deis describe svc deis-router | egrep LoadBalancer

You should see something like this:

Type:                 LoadBalancer
LoadBalancer Ingress:

The AWS name for your elastic load balancer is the string before the first - character. In this case, a5561157d2cc611e68b8802343496e12.

Now, change the timeout setting:

$ aws elb modify-load-balancer-attributes \
        --load-balancer-name a5561157d2cc611e68b8802343496e12 \
        --load-balancer-attributes "{\"ConnectionSettings\":{\"IdleTimeout\":1200}}"

Remember to replace the value in the --load-balancer-name section with the name of your load balancer.

Now the ELB is configured, we need to configure DNS so requests can be sent to applications running on Deis Workflow via the internet.

Configure DNS

To create a DNS record, you can either use your own domain name or the service. Note: the service is for demonstration purposes and should not be used in production systems.

To use the service, first pick one of the IP addresses assigned to your ELB. (We got the ELB details in the previous section.)

Run this:

$ host

You should get a response like this: has address has address

Now, construct your hostname by taking the IP address for your load balancer and adding to it.

For my example, I used the first IP address that I got: (You can use any of the IP addresses from the previous step's sample output.)

Then run:

$ host

You'll see this response: has address

The DNS answers with the same IP address, no matter the hostname. That's because is a wilcard DNS service. It maps to the corresponding IP_ADDRESS. So, maps to

Now you have a hostname to make requests to your application.

Finally, we'll need to create an admin user on your Deis Workflow installation.

Set Up Your Deis Admin

The first user to register with Deis Workflow will automatically be given admin privileges.

Using the DNS hostname from the previous step, let's create our admin user.

Run this:

$ deis register

You'll be prompted to enter the username, password, and email. Once entered, you'll be registered as admin.

However, before you can deploy an application, you'll need to generate and add keys.

You can do this by running:

$ ssh-keygen -t rsa -b 4096 -C "[email protected]"

Next, you'll be asked to select a location to save the key file and an optional passphrase.

Once keys are generated successfully, add them to the SSH agent:

$ eval $(ssh-agent) && ssh-add ~/.ssh/id_rsa

And then to Deis Workflow:

$ deis keys:add ~/.ssh/

Don't forget to change the path to key file, if you've saved it somewhere else.

This finishes Deis Workflow setup.

Let's now move on to see how to deploy an Express.js application.

Deploying an Express.js Application

Clone your application to a local directory:

$ git clone

For demo purposes, I used used a fork of the example-nodejs-express repo by Deis.

Change to the directory where the repo was cloned:

$ cd example-nodejs-express

Now create a Deis application by running:

$ deis create --no-remote

Since we didn't assign a name to the application, Deis will automatically assign a random name. In my case it was seeing-odometer.

Here is how the output should look:

Creating Application... done, created seeing-odometer
remote available at ssh://[email protected]:2222/seeing-odometer.git

Now point the Git remote at the Deis builder:

$ git remote add deis ssh://[email protected]:2222/seeing-odometer.git

Finally, push:

$ git push deis master

This should start the build process. You should see output like this:

Counting objects: 182, done.
Delta compression using up to 4 threads.
Compressing objects: 100% (86/86), done.
Writing objects: 100% (182/182), 31.40 KiB | 0 bytes/s, done.
Total 182 (delta 99), reused 168 (delta 93)
-----> Node.js app detected
-----> Creating runtime environment

Once the build is completed, you can check if your project is accessible.

Run this command:

$ curl

You'll see the message "Powered by Deis" as the output. This means curl was able to successfully connect to your deployed project.

Congrats! Everything worked.


In this post, we saw how to deploy a MEAN application on an AWS-hosted Kubernetes cluster with Deis Workflow and Helm.

We first used the script to boot up the Kubernetes cluster on EC2. Then we installed Workflow using the Helm package manager and looked at configuration. Finally we deployed a MEAN application on Workflow using the git push trigger.

Posted in Node.js, Install, Deis Workflow, AWS

triangle square circle

Did you enjoy this post?