top of page

Internal Web Application Deployment with Jenkins

  • madderle
  • Dec 1, 2017
  • 5 min read

Updated: Dec 2, 2017

Deploying web applications using Jenkins and Github.



This is a continuation of my last blog post on building internal web applications. Its very easy with small, internal application to not use best practices. But the point of this post is to provide a template and instructions so you can do the "right thing" easily. My goal is to be able to explain good practices on a smaller scale, so they can be better understood when they are being scaled up to hundreds or thousands of users. 


Deliverables

  • Standing up a release and production server (Setup Jenkins and GIT)

  • Additions to the make file to handle the data migration between production to release, release to dev, production to dev.  This protects us somewhat from overwriting production data.  The reason for this is to load data into our release or dev environments so we can interact with real data in our testing or development environments.


Easy Way


Since I am already using Git and Docker I can simply setup a deployment machine somewhere, install the necessary components like docker and git, and then manually pull the latest code whenever there is a change on the server that will serve the site. The question we must ask is, is this the “right thing” to do? 


Let me be clear about what the “right thing” is. There are lots of ways to do something. While some approaches are genuinely better than others, the “right approach” usually can be defined as the approach that reduces the most heartaches. This can be unsettling to some since it sounds subjective. But it is subjective. People value things differently, and that’s okay. Some people value ease of use.  I value automation and reducing technical debt above anything else. Ive been burned too many times. Ive spent countless hours trying to figure out why something works in development and not in production. 


While the easy way I described previously is doable, that approach can introduce mistakes. Wouldn’t it be better if we can go from development to production in a few manual steps as possible? Wouldn’t it be better if we write units tests to catch common/past problems and run them every time? Wouldn’t it be better to automate as much of the deployment process as possible so we don’t spent a lot of time on small/internal applications? 


Better Way


Yes! It would be better. What are we building?

ree

Github/Git is the source code control tool we are using to manage the different phases of the application deployment process and Jenkins is the automation tool that will orchestrate the running of tests, tagging/versioning and moving through the different phases. 



Github/Git Workflow


Here is an image that illustrates the workflow the code will move through. There are tons of blogs and articles covering the different workflows you can use with Git. I will cover a simple one. The workflow Im proposing has 3 branches: master, release and develop.

ree

Master - this branch will always reflect what is on the production server. It should never be broken and the code should always work. The goal is to keep the master branch happy. Happy happy happy.


Release - this branch is when the code is a release candidate. It has several purposes. It provides a staging area for the code that is about to go to production and no changes happens on the code. This allows you or other developers to still iterate on code without affecting code that is about to be released. Also this provides a way for people to manually test the code before it goes to production.


Development - this branch is for code under development.

Design Decision: It is important to tag the code with versions. This makes it easier to revert the code back to a known state. Every branch should leverage version tagging.

You can find a great link on GIT workflows here.


Instructions:

  1. [Github] Fork/Duplicate the template repository found here in Github and rename it.

  2. Clone the newly created repo to your local computer and select Development branch.

  3. [Development Computer] Execute the setup instructions from this blog post.

  4. [Development Computer] Commit all the appropriate files and push to the Development branch. (You may not want to commit all the files in the db folder).

  5. [Github] Push the changes to the release and master branches.



Deployment Computers


Every phase in the deployment process should have a computer/VM. Note in the above instructions steps are done on the Development Computer.

ree

Design Decision: I chose OS X as the development and release Os because I am a fan of the operating system. But it really doesn’t matter since we are leveraging Docker. Thats the beauty of Docker. But for the release server I chose OS X so the functional tests can be ran. I could do a headless tests and run Linux on the release server, but I think its a good idea to do functional tests on the browser users will be using. 

If you are interested on running headless tests you can read here.


Development Setup


If you started with the previous blog post, then Im assuming you have GIT and Docker installed already.


Release Setup

  1. Make sure Docker is installed (Instructions here)

  2. Make sure Git is installed (Instructions here)

  3. Pull from the Release Branch

  4. Install Jenkins (Instructions here)

Production Setup

  1. Make sure Docker is installed (Instructions here)

  2. Make sure Git is installed (Instructions here)

  3. Pull from the master Branch

  4. Install Jenkins (Instructions here and a guided tour here)

#ShitDidntWork I had to do some massaging to get the install to work correctly on my MacOS. I eventually went the brew install route, but needed to update my Ruby. I would suggest using Jenkins in Docker.

Jenkins Setup


You can find the post setup instructions here.


#ShitDidntWork Then I couldn't access the generate initial password to work, so I had to change the security settings and then nano into it to view the initial password. This occurred when I did not use Docker.

Once you get access Jenkins at localhost:8080, select install recommended plugins and the Pipeline and Git plugins should be installed. If not you can always go to Manage Plugins and manually add those.


The instructions to build your first pipeline can be found here. But we are going to make a slight modification. Instead of using a pipeline script you should use Pipeline script from SCM.


ree

Then select GIT from SCM, enter in the Repo URL and select the branch depending on if you are on the Release or Production server. Finally ensure Jenkinsfile is in the Script Path. This means a file named Jenkinsfile needs to be at the root of your project. (If you are using the template then it will be).

ree

Then you need to configure the build triggers are you see fit.

ree

Click Save.


Design Decision: Jenkins is an automation engine and a Jenkins pipeline script gives this automation as code. This gives teams the ability to check the file into source code and then edit, review, version and manage the pipeline as code.

Jenkins File


ree

Agent indicates that Jenkins should allocate an executor and workspace for this part of the Pipeline. Stage describes a stage of this Pipeline. Steps describes the steps to be run in the stage. sh executes the given shell command. Here we are calling the migrate_data command which calls the Django migrate command. junit is a Pipeline step provided by the JUnit plugin for aggregating test reports.

Comments


© 2017 by Brandyn Adderley

  • github-256
  • Black LinkedIn Icon
Never Miss a Post. Subscribe Now!
bottom of page