From Zero to Continuous Delivery


Imagine a world where a code update to fix a defect or add a feature is automatically pushed to a production on commit (or merged pull request) to master! We live in a time where this is now a reality for many companies of all sizes. A few large company examples are: Google, Facebook, LinkedIn, Netflix, and Etsy.

The idea of working in a continuous delivery environment has been a dream of mine. It takes a particularly high level of cultural discipline, craftsmanship, and respect to implement within an organization. Essentially all the characteristics needed to be a world class organization.

The technology and software to do so is the easy part, which will be the primary focus of this tutorial. As a result, I took the time to take a stab at creating a cloud based solution for a simple Java web application.

This blog post contains a high level overview on the concept that is continuous delivery. Then, a step-by-step walk through of getting a cloud based solution working using GitHub, Snap-Ci, and OpenShift. When a new piece of code gets pushed to the repository master branch, tests will run, and if they pass, the code will automatically be deployed to the OpenShift server gear.

Here is my simple application URL:
– http://application-dev3l.rhcloud.com/mvn-hello-world/

Summary of Continuous Delivery

In his post on Continuous Delivery, Martin Fowler states Continuous Delivery is:

A software development discipline where you build software in such a way that the software can be released to production at any time.

In addition Thought Works has a great blog post Architecting for Continuous Delivery where the author, Vishal Naik,  states:

The goal of CD is to be able to release software frequently, and reliably, in a frictionless manner.

Create A Java Web App Using Maven

Create The Java Web Application

Install GitHub and create a new  repository
– desktop.github
– Create a new repository
–   E.g: https://github.com/DEV3L/mvn-hello-world-web-app
– Clone the repository into a directory of your choice called ‘maven-hello-world’
–   Repository referenced here on out as $REPOSITORY
–   E.g.: C:\WORK\Personal\GitHub\mvn-hello-world

Download and install Java 8 JDK
Java 8 Download

Set JAVA_HOME:
– Setting-the-java_home-variable-in-windows

Download and install Tomcat 7
– Tomcat 7x Download
– Unzip Tomcat 7 into your directory of choice:
–   Referenced here on out as $TOMCAT
–   E.g.: C:\TOOLS\SERVER\apache-tomcat-7.0.67

Download Maven
– Maven Download
– Unzip maven into your directory of choice:
–   Referenced here on out as $MAVEN
–   E.g.: C:\TOOLS\Java\maven\apache-maven-3.3.9\bin
– Add maven to your path in Windows
–   How-to-setupinstall-maven-classpath-variable

Use maven to create the web-app archtype
– Maven_web_application
–   Your name/company referenced as $YOUR_NAME
–   E.g: dev3l

From the command line:

~ mvn archetype:generate -DgroupId=com.$YOUR_NAME.hello_world \
   -DartifactId=mvn-hello-world -DarchetypeArtifactId=maven-archetype-webapp \
   -DinteractiveMode=false
~ xcopy mvn-hello-world/* $REPOSITORY
~ cd $REPOSITORY
~ mvn eclipse:eclipse -Dwtpversion="2.0"

Open the project with Eclipse
– Download Eclipse
– Create/load a workspace of your choice
–   Workspace referenced as $WORKSPACE
–   E.g.: C:\WORKSPACE\Personal\mvn-hello-world

Add Tomcat 7 server to workspace
– Right click in Server tab, New -> Server
– Apache -> Tomcat v7.0 Server -> Click Next
– Browser to $TOMCAT and Click Finish

Import the web-app into the Eclipse workspace
– File -> Import -> Existing Projects in Workspace
– Select root directory as $PROJECT
– Click Finish

Update pom.xml for Java 8 and javax.servlet dependency

Add the following dependency node:

<dependency>
  <groupId>javax.servlet</groupId>
  <artifactId>servlet-api</artifactId>
  <version>2.5</version>
</dependency>

Validate no compile or build errors exist within the Markers tab

Add project to Tomcat
– Right click on the Tomcat server, click Add and Remove…
– Click Add All >>, then click Finish

Run the Tomcat server
– Click the run icon
– In your web browser of choice, navigate to:
–   http://localhost:8080/mvn-hello-world/
– You should see a page that says simply says ‘Hello World!’

hello-world-app

Commit and push code to GitHub

From the command line:

~ cd $PROJECT
~ git add *
~ git commit -m "Initial project creation"

Create The OpenShift Server

Please reference my blog post on OpenShift for step by step on how to do this
– Utilizing-openshift-to-deploy-a-web-application

For the purposes of this tutorial, we need a Java server of your choice. If you are not sure which one you need, select Tomcat 7.

open-shift-server

Create SSH Keys On Windows

Use PuttyGen to create a Windows SSH key
– PuTTY Download
– Run PuTTYgen
– Click the ‘Generate’ button and create a .ppk file
– Click the ‘Save public key’ button
–   File Name ‘id_rsa.pub’
–   Directory (for all items) ‘~/.ssh’
–     E.g.: C:\Users\Justin\.ssh
– Click the ‘Save private key’ button
–   File name ‘id_rsa.ppk’
– From the Conversions top menu select ‘Export OpenSSH key’
–   File name ‘id_rsa’

Create Snap-CI Build

Browse to Snap-CI
– Snap-CI

Follow the login process and create a free account linked to your GitHub account

Commands to be executed in this stage

My commands are as follows:

mvn test package
git clone ssh://54fa354f4382ec1767000019@application-dev3l.rhcloud.com/~/git/\
  application.git/
cp ./target/mvn-hello-world.war ./application/webapps
cd ./application
git add *
git commit -m "Install latest mvn-hello-world version"
git push

 

You will have to substitute your own OpenShift clone ssh URL.
The blog posts on OpenShift shows where this can be found.

Secure Files

– Click the ‘Add new’ link
– Select your ~/.ssh/id_rsa file
– Set the path to be a custom location of ~/.ssh/id_rsa

snap-ci-build

Update The GitHub Repository

Navigate to your GitHub repository (or do it through the command line / IDE), update any file, and watch the magic happen. It takes about a minute, but after that your new code is up and live for production use!

I like to update the index.jsp file, as this is an easy change to validate that deployment occurred.

Summary

This is a simple example that can be expanded upon by any skilled DevOpts engineer.

In it’s most ideal form, continuous delivery integrates with production in real time. But, if there are business constraints that prevent production deployments, there is no reason why a test/staging environment could not be your company’s continuous delivery target.

Feel free to contact me with any suggestions or questions!

Leave a comment