Evolve or perish! Moving towards efficient software. Containerised CI with Jenkins+Docker

Dwelling in the software entrepreneurial universe for about 3 years, I’ve had an opportunity to work on a variety of business domains, and technology stacks. In this journey I got to bootstrap a team of smart software engineers, who contributed to building quality mobile and web applications. By now we (as a team) had a good grip on the software design and development aspect of software delivery.

Mobile and Web Application Development Stack

However, we were still lacking a good workflow automation…i.e. we were not doing the deployments in an ideal way. We were spending a lot of time post- development to test, debug and deploy.
For quite some time now the CI/CD aspects that I kept reading, were left in theory; and somehow I was not able to bring these concepts on our software development floor!

Mediocrity will never do. You are capable of something better!

It was decided: If last year was dedicated to explore new software development stacks to the likes of Flutter and Swift4, then this year was definitely about exploring and learning to build an effective deployment.
Continuous Integration and Continuous Delivery being the de facto concepts of today’s software, one really has to get his/her hands wet with these software philosophies, and make them the part of the daily software development process.

In this post I’ll try to elaborate how I’ve started putting into practice the concepts which should’ve been in use yesterday!

The web applications that we’ve been building use Python Django framework. Hence, for reference we take a Python based Django web application, and see how containerisation and continuous integration can be effectively implemented for such projects.

The world is so much easy with containers. No longer do we have to keep track of all the dependencies, and the corresponding impact on the underlying workstations. Docker is something I had been reading up on off-late. Its ease of use to build and test applications, it being lightweight and fast, and its ability to enable breaking the application’s functionality into individual containers is what appealed to me.

Docker — An easy to understand, lightweight container framework

Jenkins was the first thing that came to mind while moving towards CI/CD automation.
(I’m yet to explore TravisCI, CircleCI and the likes…)

CI/CD tools to explore!

So the stage was set…we have a typical Python Django web application which is connected to a database (in our case a Postgres Db)

What we did was: Created two containers — 
- One container serves as the Database
- One container servers as the Jenkins server where the application is built and tested

Dockerfiles for every container service are specified in the application codebase itself.

All the configuration is done via docker-compose, so that all we have to do is bring the containers to life via a simple ‘docker-compose up’!

docker-compose.yml used to bring the containers to life!
Postgres and Jenkins containers up-n-running!

Once the containers are up and running. We logon to the Jenkins server, and build a pipeline job.

Create a pipeline job
Define the pipeline to read the Jenkinsfile in the repo

The pipeline job basically reads the Jenkinsfile from the repo to perform the following tasks:
a) Gets the code from the code repository (Github in this case)
b) Installs the dependencies
c) Builds the web application
d) Executes the unit tests

The Jenkinsfile defines the pipeline job steps
Jenkins Job Dashboard

The end results are available on the Jenkins dashboard for reference.

With Jenkins one can configure the job to be triggered as soon as the repo is updated, so that the build and test flow is automated and the results are available. We can also configure Jenkins to send emails to let the stake-holders know about the updates.

For everybody’s reference, I’ve built a repository for this project. The repo is available at: https://github.com/nonstopio/django_docker_jenkins.git

Feel free to use it as a boiler plate for your containerised Jenkins enabled Django projects! :)

There is a lot of scope for making this boiler plate more efficient. Hence feedback and PRs are welcome.

I intend to explore a lot more of CI/CD this year, and hope to share my learnings along the way :)

Peace \m/