Paying dinosaurs: Lessons learned from many hacky deployments with Heroku
As a hobby developer and computer science student, I find myself using Heroku to release many of my projects. Heroku is a cloud Platform as a Service (PaaS) business that provides server power for developers, and I have taken recently been taking advantage of their Free and Hobby plans.
While Heroku offers a simple, cheap solution to developers, it’s not perfect. The documentation isn’t always clear and there are many small hurdles that come up in the deployment process that can be difficult to debug. I have been working through these types of issues for the past few months, so I’ll share some of the tactics that have helped me optimize my Heroku deployments.
This is by no means a comprehensive list. Rather, these are just a few things that I’ve found to be helpful to me as a developing Heroku user.
Working with apps and dynos
Heroku allows developers to have multiple applications under one Heroku account. Heroku enforces a limit of five applications per account, unless you verify your account by adding your payment information. Giving Heroku your payment information doesn’t necessarily mean they will begin to charge you immediately. The necessity to pay for Heroku will arise when your application begins to have frequent usage.
So how is usage measured? Heroku uses dynos (which can be defined in the Procfile) to run user-specified processes (for example, the command node app.js to start your Node.js application or python app.py to start your Flask application). When your application hasn’t been accessed for a while, Heroku deactivates the dyno and restarts when it’s needed again. Therefore, the usage of your application can be measured by the amount of time that your dyno is active.
Here’s the mental metaphor that I use to remember it all: A dyno is actually a dinosaur, and as a developer you can enlist these dinosaurs to help you out by specifying processes for them to follow. If you don’t pay the dinosaurs, then they’ll work for you at most eighteen hours in a given day, and they’ll take naps after 30 minutes of being idle. If they’re working hard for all eighteen hours, then they’ll need six full hours of sleep. Luckily, if you pay the dinosaurs then they’ll be willing to stay up around the clock.
I’ve found that it’s been especially important to understand the details of dyno sleeping when using APIs that are deployed with Heroku’s free plan. Even though the hobby APIs I have worked on do not experience much traffic, requests that I send to them might timeout if the application is asleep when the request is sent. I’ve tried using code to ping the servers in order to wake up dynos before sending requests, but I have found that in those situations it may be better to use a paid Heroku plan or a different PaaS.
Setting up your application for deployment
Each time a commit is pushed to your Heroku server, it attempts to rebuild your application project. This means that each project should include a listing of the dependencies so that they can be installed in your Heroku build process. For example, a Node.js project should include a package.json file and a Flask application should include a requirements.txt file. In Node.js, you can use npm install --save to automatically add the module to the dependency listing in your package.json file. With Python-based project, one easy tool for creating your requirements.txt file is a command line tool called pipreqs.
It is also helpful to explicitly set the buildpack for your application to ensure that the correct framework is being used to build and run your application. Choose the correct buildpack and then run heroku buildpack:set buildpackname. In some cases, it may also be helpful to change the timezone for your application, especially when you’re working with time-sensitive code such as job schedulers. You can select the right timezone and then run heroku config:add TZ=”Continent/City”.
Two cool things to note: You can SSH into your Heroku server by running heroku ssh. Also, you don’t have to commit a new change to make your server rebuild. Heroku will rebuild your application when you submit an empty commit as well, so you can run git commit --allow-empty -m “empty commit” and then push it to Heroku with git push heroku master.
Checking the logs
The first step to debugging any Heroku issue is checking the Heroku logs. After installing the Heroku Command Line Interface, you can open up the directory of your Heroku project in the Terminal and type heroku logs. This command displays the log statements being printed your Heroku server. These logs will show the printed outputs coming from your application, so while you’re in the debugging state it may be helpful to add some thoughtfully placed print statements to your code to ensure that things are working as expected. Heroku will also print of the details of errors that are arising when it tries to run your application. These will be helpful to review.
So far, that’s what I’ve learned. Heroku is a really extensive platform and it can be used for many things. Please share your thoughts and advice in the comments!