Heroku was built to be managed from its command-line interface. The better we learn it, the faster and more effective we will be in administering our application. The goal of this article is to get comfortable with using the CLI. We'll see that each Heroku command follows a common pattern. Once we learn a few of these commands, the rest will be relatively simple to master.

In this article, we won't cover every command available in the CLI, but we will focus on the ones that we'll be using the most. As we learn each command, we will also learn a little more about what is happening behind the scenes so that we get a better understanding of how Heroku works. The more we understand, the more we'll be able to take advantage of the platform.

Before we start, let's note that if we ever need to get a list of the available commands, we can run the following command:

$ heroku help

We can also quickly display the documentation for a single command:

$ heroku help command_name

Viewing application logs

Logging gets a little more complex for any application that is running multiple servers and several different types of processes. Having visibility into everything that is happening within our application is critical to maintaining it. Heroku handles this by combining and sending all of our logs to one place, the Logplex.

The Logplex provides us with a single location to view a stream of our logs across our entire application. In this recipe, we'll learn how to view logs via the CLI. We'll learn how to quickly get visibility into what's happening within our application.

How to do it…

To start, let's open up a terminal, navigate to an existing Heroku application, and perform the following steps:

Heroku logs anything that our application sends to STDOUT or STDERR. If we're not seeing logs, it's very likely our application is not configured correctly.

We can also watch our logs in real time. This is known as tailing:

$ heroku logs --tail

Instead of --tail, we can also use -t.

We'll need to press Ctrl + C to end the command and stop tailing the logs.

If we want to see the 100 most recent lines, we can use -n:

$ heroku logs -n 100

The Logplex stores a maximum of 1500 lines. To view more lines, we'll have to set up a log storage.

We can filter the logs to only show a specific process type. Here, we will only see logs from our web dynos:

$ heroku logs -p web

If we want, we can be as granular as showing the logs from an individual dyno. This will show only the logs from the second web dyno:

$ heroku logs -p web.2

We can use this for any process type; we can try it for our workers if we'd like:

$ heroku logs -p worker

The Logplex contains more than just logs from our application. We can also view logs generated by Heroku or the API. Let's try changing the source to Heroku to only see the logs generated by Heroku. This will only show us logs related to the router and resource usage:

$ heroku logs --source heroku

To view logs for only our application, we can set the source to app:

$ heroku logs --source app

We can also view logs from the API. These logs will show any administrative actions we've taken, such as scaling dynos or changing configuration variables. This can be useful when multiple developers are working on an application:

$ heroku logs --source api

We can even combine the different flags. Let's try tailing the logs for only our web dynos:

$ heroku logs -p web --tail

That's it! Remember that if we ever need more information on how to view logs via the CLI, we can always use the help command:

Viewing logs via the CLI is most useful in situations where we need to see exactly what our application is doing right now. We'll find that we use it a lot around deploys and when debugging issues. Since the Logplex has a limit of 1500 lines, it's not meant to view any historical data. For this, we'll need to set up log drains and enable a logging add-on.

Searching logs

Heroku does not have the built-in capability to search our logs from the command line. We can get around this limitation easily by making use of some other command-line tools.

In this recipe, we will learn how to combine Heroku's logs with Grep, a command-line tool to search text. This will allow us to search our recent logs for keywords, helping us track down errors more quickly.

Getting ready

For this recipe, we'll need to have Grep installed. For OS X and Linux machines, it should already be installed. We can install Grep using the following steps:

To check if we have Grep installed, let's open up a terminal and type the following:

How to do it…

Let's start searching our logs by opening a terminal and navigating to one of our Heroku applications using the following steps:

To search for a keyword in our logs, we need to pipe our logs into Grep. This simply means that we will be passing our logs into Grep and having Grep search them for us. Let's try this now. The following command will search the output of heroku logs for the word error:

$ heroku logs | grep error

Sometimes, we might want to search for a longer string that includes special characters. We can do this by surrounding it with quotes:

$ heroku logs | grep "path=/pages/about host"

It can be useful to also see the lines surrounding the line that matched our search. We can do this as well. The next command will show us the line that contains an error as well as the three lines above and below it:

$ heroku logs | grep error -C 3

We can even search with regular expressions. The next command will show us every line that matches a number that ends with MB. So, for example, lines with 100 MB, 25 MB, or 3 MB will all appear:

How it works…

Like most Unix-based tools, Grep was built to accomplish a single task and to do it well. Global regular expression print (Grep) is built to search a set of files for a pattern and then print all of the matches.

Grep can also search anything it receives through standard input; this is exactly how we used it in this recipe. By piping the output of our Heroku logs into Grep, we are passing our logs to Grep as standard input.

See also

Installing add-ons

Our application needs some additional functionality provided by an outside service. What should we do? In the past, this would have involved creating accounts, managing credentials, and, maybe, even bringing up servers and installing software. This whole process has been simplified by the Heroku add-on marketplace.

For any additional functionality that our application needs, our first stop should always be Heroku add-ons. Heroku has made attaching additional resources to our application a plug-and-play process. If we need an additional database, caching, or error logging, they can be set up with a single command.

In this recipe, we will learn the ins and outs of using the Heroku CLI to install and manage our application's add-ons.

How to do it...

To begin, let's open a terminal and navigate to one of our Heroku applications using the following steps:

Let's start by taking a look at all of the available Heroku add-ons. We can do this with the addons:list command:

$ heroku addons:list

There are so many add-ons that viewing them through the CLI is pretty difficult. For easier navigation and search, we should take a look at https://addons.heroku.com/.

If we want to see the currently installed add-ons for our application, we can simply type the following:

If we ever forget any of the commands, we can always use help to quickly see the documentation:

$ heroku help addons

Some add-ons might charge you money. Before continuing, let's double check that we only have the correct ones enabled, using the $ heroku addons command.

How it works…

Heroku has created a standardized process for all add-on providers to follow. This ensures a consistent experience when provisioning any add-on for our application.

It starts when we request the creation of an add-on. Heroku sends an HTTP request to the provider, asking them to provision an instance of their service. The provider must then respond to Heroku with the connection details for their service in the form of environment variables. For example, if we were to provision Redis To Go, we will get back our connection details in a REDISTOGO_URL variable:

REDISTOGO_URL: redis://user:pass@server.redistogo.com:9652

Heroku adds these variables to our application and restarts it. On restart, the variables are available for our application, and we can connect to the service using them. The specifics on how to connect using the variables will be in the add-ons documentation. Installation will depend on the specific language or framework we're using.

Managing environment variables

Our applications will often need access to various credentials in the form of API tokens, usernames, and passwords for integrations with third-party services. We can store this information in our Git repository, but then, anyone with access to our code will also have a copy of our production credentials. We should instead use environment variables to store any configuration information for our application. Configuration information should be separate from our application's code and instead be tied to the specific deployment of the application.

Changing our application to use environment variables is simple. Let's look at an example in Ruby; let's assume that we currently have secret_api_token defined in our application's code:

secret_api_token = '123abc'

We can remove the token and replace it with an environment variable:

secret_api_token = ENV['SECRET_TOKEN']

In addition to protecting our credentials, using environment variables makes our application more configurable. We'll be able to quickly make configuration changes without having to change code and redeploy.

The terms "configuration variable" and "environment variable" are interchangeable. Heroku usually uses "configuration" due to how tightly the variables are coupled with the state of the application.

How to do it...

Heroku makes it easy to set our application's environment variables through the config command. Let's launch a terminal and navigate to an existing Heroku project to try it out, using the following steps:

We can use the config command to see a list of all our existing environment variables:

Heroku tracks each configuration change as a release. This makes it easy for us to roll back changes if we make a mistake.

How it works…

Environment variables are used on Unix-based operating systems to manage and share configuration information between applications. As they are so common, changing our application to use them does not lock us into deploying only to Heroku.

Heroku stores all of our configuration variables in one central location. Each change to these variables is tracked, and we can view the history by looking through our past releases. When Heroku spins up a new dyno, part of the process is taking all of our configuration settings and setting them as environment variables on the dyno. This is why whenever we make a configuration change, Heroku restarts our dynos.

As configuration variables are such a key part of our Heroku application, any change to them will also be included in our Heroku logs.

See also

Enabling the maintenance page

Occasionally, we will need to make changes to our application that requires downtime. The proper way to do this is to put up a maintenance page that displays a friendly message and respond to all the incoming HTTP requests with a 503 Service Unavailable status.

Doing this will keep our users informed and also avoid any negative SEO effects. Search engines understand that when they receive a 503 response, they should come back later to recrawl the site. If we didn't use a maintenance page and our application returned a 404 or 500 errors instead, it's possible that a search engine crawler might remove the page from their index.

How to do it...

Let's open up a terminal and navigate to one of our Heroku projects to begin with, using the following steps:

We can view if our application's maintenance page is currently enabled with the maintenance command:

$ heroku maintenanceoff

Let's try turning it on. This will stop traffic from being routed to our dynos and show the maintenance page as follows:

Managing releases and rolling back

What do we do if disaster strikes and our newly released code breaks our application? Luckily for us, Heroku keeps a copy of every deploy and configuration change to our application. This enables us to roll back to a previous version while we work to correct the errors in our latest release.

Heads up! Rolling back only affects application code and configuration variables. Add-ons and our database will not be affected by a rollback.

In this recipe, we will learn how to manage our releases and roll back code from the CLI.

How to do it...

In this recipe, we'll view and manage our releases from the Heroku CLI, using the releases command. Let's open up a terminal now and navigate to one of our Heroku projects by performing the following steps:

Heroku tracks every deploy and configuration change as a release. We can view all of our releases from both the CLI and the web dashboard with the releases command:

Rolling back creates a new version of our application in the release history.

We can also specify a specific version to roll back to:

$ heroku rollback v30Rolling back load-tester-rails... done, v30

The version we roll back to does not have to be an older version. Although it sounds contradictory, we can also roll back to newer versions of our application.

How it works…

Behind the scenes, each Heroku release is tied to a specific slug and set of configuration variables. As Heroku keeps a copy of each slug that we deploy, we're able to quickly roll back to previous versions of our code without having to rebuild our application.

For each deploy release created, it will include a reference to the Git SHA that was pushed to master. The Git SHA is a reference to the last commit made to our repository before it was deployed. This is useful if we want to know exactly what code was pushed out in that release.

On our local machine, we can run the $ git checkout git-sha-here command to view our application's code in the exact state it was when deployed.

Running one-off tasks and dynos

In more traditional hosting environments, developers will often log in to servers to perform basic administrative tasks or debug an issue. With Heroku, we can do this by launching one-off dynos. These are dynos that contain our application code but do not serve web requests.

For a Ruby on Rails application, one-off dynos are often used to run database migrations or launch a Rails console.

How to do it...

In this recipe, we will learn how to execute commands on our Heroku applications with the heroku run command. Let's launch a terminal now to get started with the following steps:

To have Heroku start a one-off dyno and execute any single command, we will use heroku run. Here, we can try it out by running a simple command to print some text to the screen:

How it works…

When we issue the heroku run command, Heroku spins up a new dyno with our latest slug and runs the command. Heroku does not start our application; the only command that runs is the command that we explicitly pass to it.

One-off dynos act a little differently than standard dynos. If we create one dyno in the detached mode, it will run until we stop it manually, or it will shut down automatically after 24 hours. It will not restart like a normal dyno will.

If we run bash from a one-off dyno, it will run until we close the connection or reach an hour of inactivity.

Managing SSH keys

Heroku manages access to our application's Git repository with SSH keys. When we first set up the Heroku Toolbelt, we had to upload either a new or existing public key to Heroku's servers. This key allows us to access our Heroku Git repositories without entering our password each time.

If we ever want to deploy our Heroku applications from another computer, we'll either need to have the same key on that computer or provide Heroku with an additional one. It's easy enough to do this via the CLI, which we'll learn in this recipe.

How to do it…

To get started, let's fire up a terminal. We'll be using the keys command in this recipe by performing the following steps:

If we'd like, we can also specify where the key is located if it is not in the default /.ssh/ directory:

$ heroku keys:add /path/to/key.pub

How it works…

SSH keys are the standard method for password-less authentication. There are two parts to each SSH key. There is a private key, which stays on our machine and should never be shared, and there is a public key, which we can freely upload and share.

Each key has its purpose. The public key is used to encrypt messages. The private key is used to decrypt messages.

When we try to connect to our Git repositories, Heroku's server uses our public key to create an encrypted message that can only be decrypted by our private key. The server then sends the message to our machine; our machine's SSH client decrypts it and sends the response to the server. Sending the correct response successfully authenticates us.

SSH keys are not used for authentication to the Heroku CLI. The CLI uses an authentication token that is stored in our ~/.netrc file.

Sharing and collaboration

We can invite collaborators through both the web dashboard and the CLI. In this recipe, we'll learn how to quickly invite collaborators through the CLI.

How to do it…

To start, let's open a terminal and navigate to the Heroku application that we would like to share, using the following steps:

To see the current users who have access to our application, we can use the sharing command:

How it works…

When we add another collaborator to our Heroku application, they are granted the same abilities as us, except that they cannot manage paid add-ons or delete the application. Otherwise, they have full control to administrate the application. If they have an existing Heroku account, their SSH key will be immediately added to the application's Git repository.

See also

Monitoring load average and memory usage

We can monitor the resource usage of our dynos from the command line using the log-runtime-metrics plugin. This will give us visibility into the CPU and memory usage of our dynos. With this data, we'll be able to determine if our dynos are correctly sized, detect problems earlier, and determine whether we need to scale our application.

How to do it…

Let's open up a terminal; we'll be completing this recipe with the CLI by performing the following steps:

First, we'll need to install the log-runtime-metrics plugin via the CLI. We can do this easily through heroku labs:

$ heroku labs:enable log-runtime-metrics

Now that the runtime metrics plugin is installed, we'll need to restart our dynos for it to take effect:

$ heroku restart

Now that the plugin is installed and running, our dynos' resource usage will be printed to our logs. Let's view them now:

From the logs, we can see that for this application, our load average is 0, and this dyno is using a total of 105 MB of RAM.

How it works…

Now that we have some insight into how our dynos are using resources, we need to learn how to interpret these numbers. Understanding the utilization of our dynos will be key for us if we ever need to diagnose a performance-related issue.

In our logs, we will now see load_avg_1m and load_avg_5m. This is our dynos' load average over a 1-minute and 5-minute period. The timeframes are helpful in determining whether we're experiencing a brief spike in activity or it is more sustained. Load average is the amount of total computational work that the CPU has to complete. The 1X and 2X dynos have access to four virtual cores. A load average of four means that the dynos' CPU is fully utilized. Any value above four is a warning sign that the dyno might be overloaded, and response times could begin to suffer. Web applications are typically not CPU-intensive applications, seeing low load averages for web dynos should be expected. If we start seeing high load averages, we should consider either adding more dynos or using larger dynos to handle the load.

Our memory usage is also shown in the logs. The key value that we want to keep track of is memory_rrs, which is the total amount of RAM being utilized by our application. It's best to keep this value no higher than 50 to 70 percent of the total RAM available on the dyno. For a 1X dyno with 512 MB of memory, this would mean keeping our memory usage no greater than 250 to 350 MB. This allows our application's room to grow under load and helps us avoid any memory swapping. Seeing values above 70 percent is an indication that we need to either adjust our application's memory usage or scale up.

Memory swap occurs when our dyno runs out of RAM. To compensate, our dyno will begin using its hard drive to store data that will normally be stored in RAM. For any web application, any swap should be considered evil. This value should always be zero. If our dyno starts swapping, we can expect that it will significantly slow down our application's response times. Seeing any swap is an immediate indication that we must either reduce our application's memory consumption or start scaling.

See also

Load average and memory usage are particularly useful when performing application load tests.

Summary

In this article, we learned various commands on how to view application logs, installing add-ons, viewing application logs, enabling the maintenance page, managing SSH keys, sharing and collaboration, and so on.

Alerts & Offers

Series & Level

We understand your time is important. Uniquely amongst the major publishers, we seek to develop and publish the broadest range of learning and information products on each technology. Every Packt product delivers a specific learning pathway, broadly defined by the Series type. This structured approach enables you to select the pathway which best suits your knowledge level, learning style and task objectives.

Learning

As a new user, these step-by-step tutorial guides will give you all the practical skills necessary to become competent and efficient.

Beginner's Guide

Friendly, informal tutorials that provide a practical introduction using examples, activities, and challenges.

Essentials

Fast paced, concentrated introductions showing the quickest way to put the tool to work in the real world.

Cookbook

A collection of practical self-contained recipes that all users of the technology will find useful for building more powerful and reliable systems.

Blueprints

Guides you through the most common types of project you'll encounter, giving you end-to-end guidance on how to build your specific solution quickly and reliably.

Mastering

Take your skills to the next level with advanced tutorials that will give you confidence to master the tool's most powerful features.

Starting

Accessible to readers adopting the topic, these titles get you into the tool or technology so that you can become an effective user.

Progressing

Building on core skills you already have, these titles share solutions and expertise so you become a highly productive power user.