This article by Gergely Nemeth was originally published on the RisingStack Engineering blog and we are happy to republish it here for Codeship readers. Gergely is an engineer at RisingStack where he helps companies changing from monolithic applications to Node.js-based microservices.
Setting up continuous deployment of Node.js applications now is easier than ever, especially now that we have tools like Codeship for Continuous Integration and Delivery. In this article we are going to use Codeship with Docker and Ansible to deploy our Node.js application. A key principle I want to emphasize before diving deeper is immutable infrastructures, what they are and how they can make your life easier.
Immutable infrastructures usually consist of data and everything else. The everything else part is replaced on each deploy. Not even security patches, or configuration changes happen on production systems. To achieve this we can choose between two approaches: the machine-based and the container-based approaches.
Machine-based immutability can happen like this: on each deploy you set up entirely new EC2 machines and deploy your applications on them. If everything is okay, then you simply modify your load balancer configuration to point to your new machines. Later on you can delete the old machines.
You can think of the container-based approach as an improvement of the machine-based one: on one machine you can have multiple containers running. Docker makes this relatively easy. Docker is an open platform for developers and sysadmins to build, ship, and run distributed applications. Sure, you could use VMWare or VirtualBox for the container-based way, but while a Docker start takes seconds, the others take minutes.
Advantages of Immutable Infrastructures
In order to full take advantage of this approach, you should have a Continuous Delivery pipeline set up, with tests and orchestration as well. The main advantages:
Going back to older versions is easy
Testing the new infrastructure in isolation is possible
Simplify change management as servers never rot
It is time to get our hands dirty! We are going to create and deploy a Hello Docker & Codeship application. For this, we are going to use this github project. It is a simple application that returns the "We <3 Docker & Codeship" string via HTTP. Here is what we are going to do: - When someone pushes to the controller branch, GitHub will trigger a build on Codeship - If everything is OK, Codeship triggers a build on Docker Hub - After the new Docker image is ready (pushed), Docker triggers a webhook - Ansible pulls the latest image to the application servers (Docker Deployer)
Create a Docker Hub account
What is Docker Hub? Docker Hub manages the lifecycle of distributed apps with cloud services for building and sharing containers and automating workflows.
Go to Docker Hub and sign up.
Setting up a Docker repository
After signing up, and adding your GitHub account, go under My Profile > My Repositories > Add repositories and click Automated build. After setting up your repository, enable Build triggers. This will result in a command similar to this:
$ curl --data "build=true" -X POST https://registry.hub.docker.com/u/gergelyke/docker-codeship-project/trigger/TOKEN/
Also make sure, that you deactivate the GitHub commit hook under Automated build - remember, Codeship will listen on commits to the git repository. That's it, your Docker Hub is ready to be used by Codeship.
Get a Codeship account and set up your repository
Go to Codeship, and get an account.
After registering, you can connect to your GitHub or BitBucket account from Codeship. After you have given access to Codeship, you will see you repositories listed. Here I chose the repository mentioned before. Then choose Node.js and click "Save and go to my dashboard".
Modify your Deploy Commands
Under the deploy settings, choose custom script - insert the previously generated curl command from Docker Hub. That's it!
The Docker Deployer
This part does not come out of the box. You have to implement a little API server, that listens to the Docker Hub webhook. When the endpoint is called, it runs Ansible, that pulls the latest Docker image available to the application servers. Note: of course, you are not limited to use Ansible - any other deploy/orchestration tool will do the job.
Always keep shipping
As you can see, setting up a Continuous Delivery pipeline with immutable infrastructure can be achieved easily - not only can it be used in your production environments, but staging or development environments as well.