Django Deployment with Jenkins Pipelines and Chef — Part 1

Eugene Vasilchenko
Ordergroove Engineering
4 min readDec 16, 2016

--

Plan, Prepare and Test

Tutorial Index

Part 1 — Plan, Prepare and Test (Reading Now)
Part 2 — Creating Django Artifacts and Chef Deployment

In this first part of a series of posts, we will start our journey toward continuous deployment. We will cover some basic concepts, but we’ll assume that you’re already aware of Jenkins pipelines and have had some experience working with Django-based applications.

Planning Is Everything

You are probably familiar with the expression, “measure twice, cut once”. This advice is something that you should really take to heart when building out your deployment pipelines. I know that this sounds obvious (and it is), but believe me, you will save yourself a lot of headaches if you just spend a little bit more time planning ahead.

You should start by writing out your entire deployment process. Outline all the steps which are necessary for your deployment, but try to keep it high-level in the beginning. Use vim, pen & paper or grab a white-board. It really doesn’t matter.

Here is a simplified example set:

Pro-tip: Be sure to take a photo if you’re writing these out on a white-board.

After you put together the initial list, you should meet with other stakeholders to review it. The best group of people to review these steps are typically the developers, the testers and your dev-ops team (if you’re lucky enough to have them). This review should really be no longer than a half hour - just to ensure that you’re all on the same page. Don’t be afraid to dive into discussion, but save true debates for the code review of your Jenkinsfile.

Prepare your Application and Run Tests

Now that everyone is on-board with your deployment plan, it’s time to start writing your Jenkinsfile. Your list of deployment steps can be translated to stages in the build process. Without going too deep into details, a pipeline stage is a way for you to group tasks that logically belong together. An added bonus to this step is that stages are used to display a very clear and interactive progression bar. Complete this with built-in timers that allow you to easily find and improve slow deployment steps within your process. You can learn more about stages and other common pipeline terms here.

It’s often recommended to you install and run a Django project inside a virtual environment. This way you can manage all of your dependencies without affecting the rest of your system. Django documentation recommends using virtualenv or virtualenvwrapper for this purpose. For the very first stage of our pipeline, we’re going to assume that virtualenv is installed and available on the Jenkins server. The code below will first check to see if a virtual environment already exists within the current workspace, and if not, it will create one using a shell command.

Now that we have our virtual environment installed, it’s time to get the latest version of our code. Since this is a multi-branch project, the built-in checkout scm command is used. This command will pull down the code and automatically check out the branch triggering this build. If you’re working with a standard pipeline project, then you would replace this with the regular git url: pipeline command instead.

The next stage in deploying your application would be to install all of your application dependencies. The following code will activate the virtual environment, install all of your application dependencies and then deactivate the virtual environment. This code assumes that your application dependencies live in a nicely structured, scm controlled requirements file. Please note that a triple-quote syntax is used to define this shell script. This tells Jenkins that what follows is a series of separate shell commands separated by a new-line character.

Django recommends that static assets such as images, javascript and css are served through a separate folder of your web server or through a CDN. In order to prepare these assets, we are going to run the built-in collectstatic command. Please note that collectstatic causes an input prompt, so we’re using the ‘ — noinput’ parameter to ensure that the build doesn't pause or stop running.

After you collect your static files, it’s time to run the test suite. You can use any number of test runners, including the built-in django test runner, nose or tox. For our example, we’re going to use a great library called django-jenkins. This library enables us to seamlessly run our test suite and generate a junit report regarding our tests. You will notice that the command itself is inside a try-catch-finally block. We will attempt to run the suite, catch any exceptions and mark the build as a failure.

Depending on your build pipeline, you might choose to separate the stages above to be run by different nodes. For sake of brevity, please find the culmination of all of our stages below in a single node:

This concludes Part 1 of the tutorial. In the next chapter, we’ll dive into creation of django artifact files and start working on the actual deployment process.

Click Here for Part 2

Image Credits
Icons made by Freepik and Pixel Perfect from www.flaticon.com
Django, Chef and Jenkins icons are properties of their respective owners

--

--