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!’
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.
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
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!