Deploying to Heroku

3 minute read

This article is about deploying to Heroku using CloudBees CodeShip Pro. If you are unfamiliar with CloudBees CodeShip Pro, we recommend our getting started guide or the features overview page. You can find a sample repository for deploying to Heroku with CloudBees CodeShip Pro on GitHub here.

To make it easy for you to deploy your application to Heroku we’ve built an image that you can add to your codeship-services.yml file and use in your codeship-steps.yml file.

This image will support both a standard Heroku deployment by using the Heroku Toolbelt CLI to let you run Heroku deployment command, as well as a Docker deployment to Heroku by letting you push an image to Heroku’s image registry to trigger your deployment.

Authentication

Heroku API Key

Before setting up the codeship-services.yml and codeship-steps.yml files, you will need to create an encrypted environment file that contains the Heroku API key.

This will be done by using CloudBees CodeShip Pro’s encrypted environment files feature, which allows you to add your environment variables through an encrypted file placed in your repository. In this example, the file will be called heroku-deployment.env.encrypted and will encrypt the following data at a minimum:

HEROKU_API_KEY=your_api_key_here

You can get the Heroku API key from your Heroku Dashboard or other methods outlined in the Heroku documentation.

Heroku Deployment Container

In the codeship-services.yml file, you will add a new service definition in addition to your primary application services. This definition will be for an image that will create the deployment container, which is the container all Heroku authentication and deployment commands will execute on.

Note that CodeShip maintains an image for this purpose. All you need to do is include it and provide your API key through the encrypted file discussed above, as well as set a host volume so that you can share data with your primary containers.

heroku-deployment: image: codeship/heroku-deployment encrypted_env_file: - heroku-deployment.env.encrypted volumes: - ./:/deploy

Deploying To Heroku

Deployment Option #1: Platform Deployment

If you are not using Heroku’s Docker support to run Docker in production, you will most likely want to deploy using Heroku CLI commands and the Heroku Platform API. By using the Platform API, no SSH key management is necessary.

The deployment container discussed above has a codeship_heroku deploy command that you need to call, along with the path to your application. In this example, the path to our application is actually coming through our separate, application container via a host volume (in this case /deploy). You will also need to provide your application name. The default script will then check that it has access to the application and deploy it.

- service: heroku-deployment command: codeship_heroku deploy /deploy codeship-heroku-deployment - service: heroku-deployment command: heroku run --exit-code --app codeship-heroku-deployment -- bundle exec rake db:migrate

Additionally, if you provide the location of the application that should be deployed then you can also deploy subfolders of your app, or even run different commands on your codebase before deploying it. These optional specifications will give you more granular control over your deployment steps.

Also note above that the deployment container has the Heroku Toolbelt installed you can use other Heroku commands in further steps, e.g. to run your database migrations.

Deployment Option #2: Docker Deployment

If you are using Heroku’s Docker support, you can trigger a deployment simply by doing an image push to the Heroku registry.

On CloudBees CodeShip Pro, a push step happens in your codeship-steps.yml file and requires that we generate an authentication token to authenticate with the Heroku registry. CodeShip maintains an image that you will use to generate your authentication token, simply add it to your codeship-services.yml file and provide your Heroku API key via the encrypted environment variables file discussed above.

app: build: image: registry.heroku.com/your_image_name/web dockerfile: Dockerfile encrypted_env_file: - heroku-deployment.env.encrypted heroku-dockercfg-generator: image: codeship/heroku-dockercfg-generator add_docker: true encrypted_env_file: - heroku-deployment.env.encrypted

This codeship/heroku-dockercfg-generator image will be used on our image push step, and is configured to automatically generate the token using the API key provided in the encrypted environment variables file.

Once we have this service in place, we can push to the Heroku registry in our codeship-steps.yml file and subsequently trigger a release:

- name: Push Image service: app type: push image_name: registry.heroku.com/your_image_name/web registry: registry.heroku.com dockercfg_service: heroku-dockercfg-generator - name: Trigger Release service: heroku-deployment command: heroku container:release --app your_image_name web

Note that the dockercfg_service directive calls the heroku-dockercfg-generator specified above to generate our token. The only variable you need to be sure to modify is your_image_name, which must be set to the name for the application image you are pushing as defined in your codeship-services.yml file.