Faster Heroku Deploys reusing slugs between applications

At Helpling we deploy the same code to several different Heroku applications. When using the traditional deploy system in Heroku, they take the code, download dependencies, generate assets and pack it all in what Heroku calls a Slug.

When you deploy the same code to several applications, this process is repeated for all of them resulting in an identical Slug in all cases. That always bothered us, because it seemed a bit inefficient.

Some months ago, David found this article Copying Slugs with the Platform API and we kept the link to it in out tech backlog.

Some weeks ago I managed to spend some time with it and we managed to reduce our deploy to production time from ~13minutes to <2 minutes.

I’m so happy about it that I have decided to inaugurate our Tech Blog with a small example.

Goal

  • Deploy our code to a Staging with the traditional method
  • Deploy the same code to production reusing the staging’s slug

Prerequisites

  • Have the system configured to deploy on Heroku
  • Have a HEROKU_API_KEY env var for a user with access to both Staging and Production
  • Have jq accessible in your console

Step 1: Deploy to Staging

Run the standard commands to push your branch to the git remote from Heroku:

git remote add heroku-staging https://git.heroku.com/heroku-staging.git
git push --force heroku-staging master

Step 2: Obtain the slug id

This command will call the Platform API to obtain the latest released slug_id on the heroku_staging app:

SLUG_ID="$(curl -H "Authorization: Bearer $HEROKU_API_KEY" -H "Accept: application/vnd.heroku+json; version=3" -n https://api.heroku.com/apps/heroku-staging/releases | jq ".[-1].slug.id" -r)"

Extra: If you want to check the revision you can run this:

SLUG_DESCRIPTION="$(curl -H "Authorization: Bearer $HEROKU_API_KEY" -H "Accept: application/vnd.heroku+json; version=3" -n https://api.heroku.com/apps/heroku-staging/releases | jq ".[-1].description" -r

Step 3: Deploy to Production

Now it’s as easy as calling the Platform API to tell the heroku-production app to use the slug in SLUG_ID:

curl -H "Authorization: Bearer $HEROKU_API_KEY" -H "Accept: application/vnd.heroku+json; version=3" -H "Content-Type: application/json" -X POST -n  -d "{\"slug\": \"${SLUG_ID}\"}" https://api.heroku.com/apps/heroku-production/releases

Site Footer