Skip to main content

Tomasz Knapik

← Tech blog

Deploying dockerised applications on Heroku

I love Heroku for how effortless it is to deploy simple Docker web apps on the platform. You are all set if your dockerised app follows the twelve-factor philosophy. It just works and the platform is just stable. I love the fact that you do not have to add a number of complicated configuration files specific to a single cloud provider. It keeps your application very portable.

I love to use it when I want to spend little to no effort and have things working without stress or navigating complicated UIs or writing complicated configuration files.

1. Use the PORT variable

Make sure your application server uses PORT environmental variable. If you are like me and you use Gunicorn, it understands it out of the box so no need to do anything.

For something like uWSGI you may want to tweak your Dockerfile to use the variable.:

CMD uwsgi --http-socket :{$PORT} uwsgi.ini

2. Create the Heroku YAML file

Add a one, simple file at the root of your repository - heroku.yml. It tells Heroku what processes to run and what Dockerfile to use. It will build the image on the Heroku servers after the git push so no need to have a complicated CI pipeline or your own container registry if you only need to build a simple image.

# heroku.yml
build:
  docker:
    web: Dockerfile
release:
  image: web
  command:
    - django-admin migrate

I think that file is simple and it does not have to be more complicated. I tell Heroku where my Dockerfile is and what commands to run at the release. In my example I run database migrations.

More information about heroku.yml can be found in the Heroku documentation.

3. Use container stack

By default Heroku uses the “buildpacks”. To create an app with container stack you can use the following command:

heroku apps:create --stack container your-app-name

Or change the stack of an existing application:

heroku stack:set -a your-app-name container

4. Provision backing services - Heroku add-ons

If you need a database, scheduler or cache store, you can just provision an add-on. Some examples below.

heroku addons:add heroku-postgresql
heroku addons:add heroku-redis
heroku addons:add scheduler

It automatically sets you with DATABASE_URL and REDIS_URL. If you follow the twelve-factor app, your app should understand those variables already. You can add any additional environment variables you need with the CLI, e.g. heroku config:set SECRET_KEY=test-secret-key. Easy. Need automatic backups of your database? Run heroku pg:backups schedule --at "02:00 UTC".

More about add-ons can be found in the Heroku documentation.

Pricing

If you just run a simple app that has not many visitors, you could run it at no cost. The only caveat is that your dyno (Heroku process) will sleep after 30 minutes of inactivity.To prevent that you could just ping it from another server or use some sort of monitoring service that will do it for you. If you want to share an app with a team, you can’t do it on the free plan.

The cheapest plan starts at $7 a month. You can turn off the app whenever you don’t need it to be online to save the money since the costs are prorated to the second.

If you plan to run a resource hungry or traffic heavy, the prices will grow exponentially. Good news is that you are not locked in and your application is generic enough to move it to something like AWS.