Continuous Deployment With Heroku and Github
Zone Leader Sam Atkinson teaches us about using Heroku and GitHub to build a Continuous Deployment pipeline.
Join the DZone community and get the full member experience.Join For Free
The movement to Continuous Deployment (CD) has been gathering speed and is widely acknowledged as the way to go. Code is checked in, an automated suite is run, and if passed it is automatically deployed into production. A story is not “done” until it is in production, providing value to the end user and CD gives us the smallest mean time to production for our code. To get to this point we have to have a lot of faith in our test suite and the code base, which ensures we will write more robust systems to cope with this way of working.
There still isn’t a huge heap of tooling available to build a continuous deployment pipeline; it tends to be something people have manually crafted using tools such as Puppet, Ansible and Chef. That’s why when I went to put a project up on Heroku for the first time in a while I was pleasantly surprised to see it now supports building your code from GitHub and continuous deployment from that repository.
Let's first discuss what Heroku brings the table. It’s a great place to deploy your applications and services in a scalable fashion. You can pretty much just drop any application in any language onto Heroku and it’ll spin it up for you, accessible for the world. Your app is scalable on a simple web dashboard too; start out with a single dyno, but increase if you need the capacity. There’s lots of awesome addons you can throw on too such as papertrail for log alerting and HTTPS certificate hosting. The addons vary in price, but to get a simple process up and running is totally free.
This tutorial presumes you’ve signed up for an account at heroku.com and you have an existing Java web project you’d like to set up for CD which is already in Github.
Step 0: Github Build
As with any good continuous integration you want to make sure your tests are all run first. Fortunately this is easy to do with Github and TravisCI. You can sign up using your Github account at Travis-CI.org which will then allow you to easily create automated builds which are triggered on every check-in.
Once you’ve signed in, you will be given a list of all your repositories. Flick the toggle switch for the project that you’re setting up, in my case WizChat.
Travis requires a config file to be placed in the root of your project names .travis.yml. Although there’s a variety of options you can choose to setup, for the purpose of this example I went with the simplest options; telling Travis the project is Java and to build using Oracle JDK 8
Check this in and your first build will be automatically triggered. If everything is setup correctly in your project, and your tests are passing, Travis will give you a green build. Either way it should send you an email to let you know.
For bonus marks, once you’ve completed your first build you will see a badge indicating the build status. Click this and you’ll be given a variety of ways to integrate the build badge into other sites. Convention dictates placing it at the top of the readme for your project. As my readme is in Markdown format I simply copy and paste the Markdown syntax provided:
Setting Up Your Project for Heroku
As mentioned before, it’s possible to throw pretty much anything at Heroku and have it run. All it requires first is the creation of a Procfile, used by Heroku to know what to run and how.
For web projects it only requires a single line. Again, there’s lot of extended config that you could dig into if you need finer grain control, but the following should be sufficient to get your web project going:
web: java -jar target/wizchat.jar
This tells Heroku the command to run, and that the project is a web project so it needs to let us know what the port is which is done via a system variable. You need to ensure that your project runs on whatever port is handed to it by Heroku else your application won’t run. For example, this is done in SparkJava using the following syntax:
For our Procfile to work it also relies on us having a runnable Jar. This can easily be achieved using the Maven assembly plugin, or the Maven shade plugin.
<plugins> <plugin> <artifactId>maven-assembly-plugin</artifactId> <configuration> <archive> <manifest> <mainClass>com.samatkinson.Main</mainClass> </manifest> </archive> <descriptorRefs> <descriptorRef>jar-with-dependencies</descriptorRef> </descriptorRefs> <finalName>wizchat</finalName> <appendAssemblyId>false</appendAssemblyId> </configuration> <executions> <execution> <id>make-assembly</id> <phase>package</phase> <goals> <goal>single</goal> </goals> </execution> </executions> </plugin> </plugins>
This code builds a single fat executable jar with all the dependencies built in. You must set the mainClass and finalName and Maven does the rest.
With everything checked in we now head over to Heroku and login to the dashboard. In the top right is an arrow. Click on it and select “Create new app”.
Create a name for your app and select in which region you’d like to run it.
You can then choose the deployment method: select Github and sign into your Github account when prompted. This should integrate and pull al of your repos in. Search for and select the repository you’re integrating and press “Connect”.
For the final step, select “Wait for CI to pass before deploy” and click Enable Automatic Deploys. You will now have automated deployment of your application to Heroku every check in if the CI passes! Your application will be available at <appname>.herokuapp.com.
I highly advise setting up the Heroku Toolbelt so that you can then tail the logs of your application to make sure it started correctly.
If you've any comments or questions leave them in the comments section or follow me on Twitter via @SambaHK.
Opinions expressed by DZone contributors are their own.