Heroku is an easy way to host your apps. It is simple and runs in the cloud - so you avoid the need for servers and a lot of infrastructure automation scripting. Unfortunately, there aren’t many good Continuous Integration or Continuous Delivery options that can run on Heroku1, so if you’re a firm believer in CI/CD you will still need some servers outside of Heroku.
So, how do you add Heroku deployments into you pipeline if you are running a CI server outside heroku? This Jenkins setup is working for me:
Heroku Setup
If you don’t already have multiple environments in Heroku, you’ll need to set that up. Check out the Heroku guide on Managing Multiple Environments for an App.
tl;dr: Heroku environments are really distinct apps. They each have their own set of plugins and collaborators, so make two apps with the same plugins. I wouldn’t share the collaborators - the team can push to CI, but only CI should push to production.
Here’s an sample of a two-environment setup:
1 2 |
|
Jenkins Setup
Here’s what you need to do on the Jenkins side:
Plugins
Install Jenkins GIT plugin
Create the Post Deploy Job
Create a new job named your-app-postdeploy. It should run whatever is necessary to complete a deployment after a git push to Heroku. Probably something along the lines of:
1
|
|
Setup both Git repos as SCMs
Setup the build
Setup whatever your CI would normally do if you weren’t using Heroku environments. If your CI tests include an integration phase that hits http://your-app.heroku.com then you should probably include the same steps as your post-deploy job (with –app your-app).
Setup the merge and push
Setup the post-deploy trigger
Summary
This should get you Continuous Deployment from Jenkins to Heroku. There are a couple caveats:
- You may get a merge conflict if someone manually pushes changes to production that were not pushed through your-app/master. You shouldn’t do that anyways.
- This is Continuous Deployment, not Continuous Delivery. You would need to make some changes to support a manual gate before production. The only opportunity this provides for a manual gate (between deployment and post-deployment) is not a viable option.
- Your application may be broken between the deploy and post-deploy. This is usually just a few seconds. You could briefly enable Heroku maintenance mode if the user experience is an issue.
-
Travis-CI is one. It only seems to support public GitHub repos and is still in alpha. Tddium is another. It is a paid service and Heroku does not currently recommend allowing it to push to production.↩