I am using Heroku for a long time now. The usual deployment method for me was to push a Git repository to Heroku, then build and run the software in their cloud. Since a long time, Heroku supports also Docker deployment, but in the past I found it a bit to restrictive. Now it is possible to deploy web applications as Docker images very easily. As an example I have a continuous delivery pipeline (using Travis CI) up and running that deploys the same docker image to both DockerHub and Heroku. As base I take my Open Source Playground Chatty. In this blog I explain how this is done.
One restriction of the Heroku Docker deployment is that the web server has to run on a port specified by the environment variable PORT. In Spring there are many ways for doing this. I decided to manually override Springs’s server.port property, when the application finds out at run-time that it is running in an Heroku environment, checking the environment variables DYNO and PORT:
public static void main(String[] args) throws Exception { String ENV_PORT = System.getenv().get("PORT"); String ENV_DYNO = System.getenv().get("DYNO"); if(ENV_PORT != null && ENV_DYNO != null) { System.getProperties().put("server.port", ENV_PORT); } SpringApplication.run(Chatty.class, args); }
To do a Docker deployment, you have to login into the Heroku registry first. For that you need to know the your Heroku auth token. The easiest way to get it is to login to Heroku using the CLI and then type
heroku auth:token
This will return a token like ea405d9e-76ff-4881-acbd-327c28efa3be. Now you can login to the Heroku Docker registry with
docker login --email=_ --username=_ --password="ea405d9e-76ff-4881-acbd-327c28efa3be" registry.heroku.com
Then you have to tag your Docker image like
docker tag <image> registry.heroku.com/<app>/<process-type>, e.g. docker tag kaitoedter/chatty registry.heroku.com/chatty42/web
You could simply put the scripting in a .travis.yml file and hide the Heroku auth token in an environment variable, like
- docker login --email=_ --username=_ --password="$HEROKU_AUTH_TOKEN" registry.heroku.com - docker tag kaitoedter/chatty registry.heroku.com/chatty42/web - docker push registry.heroku.com/chatty42/web
You find the Chatty .travis.yml here.
A running container is always available at https://chatty42.herokuapp.com
Since Heroku is shutting down the service when there are no users, please give it a bit of time to start up.
As conclusion I find the deployment of custom Docker images to Heroku even easier than the previous git deployment.