Useful Heroku CLI commands
Tags: heroku, ci, webdev, cli
Published: 2019-11-19 08:48:36

Many of us use Heroku on a daily bases but are not aware of some interesting and useful CLI commands that may help you in your everyday work. Here we will take a look at some useful Heroku CLI commands.

# heroku apps:info

<pre>
<b>OPTIONS</b>
  <i>-a, --app=app        app to run command against
  -j, --json
  -r, --remote=remote  git remote of app to use
  -s, --shell          output more shell friendly key/value pairs</i>
</pre>
If you want to check some basic information about your app that is running on Heroku, you can do so from your CLI. The command and output look something like this:

<pre>
<b>heroku apps:info -a name-of-your-app</b>

<i>=== name-of-your-app
Addons:         heroku-postgresql:standard-0
                heroku-redis:premium-0
                timber-logging:free
Auto Cert Mgmt: false
Dynos:          web: 2, worker: 1
Git URL:        https://git.heroku.com/name-of-your-app.git
Owner:          owner@heroku.com
Region:         eu
Repo Size:      234 MB
Slug Size:      234 MB
Stack:          heroku-18
Web URL:        https://name-of-your-app.herokuapp.com/</i>
</pre>

# heroku buildpacks:search [term]

<pre>
<b>ARGUMENTS</b>
  <i>TERM  search term that searches across name, namespace, and description</i>

<b>OPTIONS</b>
  <i>--description=description  buildpack description to filter on

  --name=name                buildpack names to filter on using a comma
                             separated list

  --namespace=namespace      buildpack namespaces to filter on using a comma
                             separated list</i>
</pre>

You probably know that you can add or remove buildpacks but one useful command is the buildpack search command. Let's say you want to search for the **elastic** buildpack, you can find it easily:

<pre>
<b>heroku buildpacks:search elastic</b>

<i>Buildpack                                   Category  Description
──────────────────────────────────────────  ────────  ───────────────────────────────────
doctolib/heroku-buildpack-ci-elasticsearch  tools     Installs an in-dyno ElasticSearch …

1 buildpack found</i>
</pre>

Then you can eventually add the buildpack you just found and see that it is added to the bottom of your buildpacks list. One thing to notice is that this newly added buildpack will be applied to your app the next time you deploy, not instantly:

<pre>
<b>heroku buildpacks:add doctolib/heroku-buildpack-ci-elasticsearch -a name-of-your-app</b>

<i>Buildpack added. Next release on your-app-name will use:
  1. heroku/nodejs
  2. https://github.com/mojodna/heroku-buildpack-jemalloc
  3. heroku/ruby
  4. doctolib/heroku-buildpack-ci-elasticsearch</i>
</pre>

# heroku ci

<pre>
<b>OPTIONS</b>
  <i>-a, --app=app            app name
  -p, --pipeline=pipeline  name of pipeline
  --json                   output in json format
  --watch                  keep running and watch for new and update tests</i>
</pre>

If you want to check the latest test runs for a given app or pipeline, you can do so with this command:

<pre>
<b>heroku ci -a name-of-your-app</b>

<i>=== Showing latest test runs for the lab pipeline
✓  2961  last_commit                fbe70c8  succeeded
✓  2960  second_commit              4615132  succeeded
✗  2959  first_commit               a3563a9  failed</i>
</pre>

# heroku:ci debug

<pre>
<b>OPTIONS</b>
  <i>-a, --app=app            app to run command against
  -p, --pipeline=pipeline  pipeline
  -r, --remote=remote      git remote of app to use
  --no-cache               start test run with an empty cache
  --no-setup               start test dyno without running test-setup</i>
</pre>

One problem that some of you might have seen is tests that pass locally but fail on your Heroku CI. This command opens a new debug test run. This enables you to inspect the Heroku CI environment and the execution of tests inside a test dyno. It will first start the test setup script (if one is present) and then open a new terminal window from inside the new debug dyno, so you can run your tests from inside the CI.

<pre>
<b>heroku ci:debug -a name-of-your-app</b>

<i>Preparing source... done
Creating test run... done
Running setup and attaching to test dyno...
...
~ $</i>
</pre>

# heroku config:edit [key]

<pre>
<b>ARGUMENTS</b>
  <i>KEY  edit a single key</i>

<b>OPTIONS</b>
  <i>-a, --app=app        (required) app to run command against
  -r, --remote=remote  git remote of app to use</i>
</pre>

If you want to quickly edit a config variable that you have in your app, this is a great way. It opens the default text editor set by $VISUAL or $EDITOR. After editing and saving your file, you will be asked to confirm your edit by typing "yes" at the prompt.

<pre>
<b>heroku config:edit APP_DISTRIBUTOR -a name-of-your-app</b>

<i>Fetching config... done

Config Diff:
APP_DISTRIBUTOR=test
APP_DISTRIBUTOR=test-new

Update config on ⬢ name-of-your-app with these values?:
Update config on ⬢ name-of-your-app with these values?: yes
Updating config... done</i>
</pre>

# heroku ps:scale

<pre>
<b>OPTIONS</b>
  <i>-a, --app=app        (required) app to run command against
  -r, --remote=remote  git remote of app to use</i>
</pre>

To resize your dynos you can use the ps:scale option. If you enter the command without any options you will see the current dyno formation:

<pre>
<b>heroku ps:scale -a name-of-your-app</b>

<i>console=0:Standard-1X rake=0:Standard-1X release=0:Standard-1X web=2:Standard-1X worker=1:Standard-1X</i>
</pre>

Let's say you want to scale your worker count up, you can do this in 2 ways:

1.
<pre>
<b>heroku ps:scale worker=2:Standard-1X -a name-of-your-app</b>

<i>Scaling dynos... done, now running worker at 2:Standard-1X</i>
</pre>

2.
<pre>
<b>heroku ps:scale worker+1 -a name-of-your-app</b>

<i>Scaling dynos... done, now running worker at 2:Standard-1X</i>
</pre>

The same goes for scaling down, you can type the exact dyno formation you want or you can decrease it with the dash ( - ) sign.

# heroku logs

<pre>
<b>OPTIONS</b>
  <i>-a, --app=app        (required) app to run command against

  -d, --dyno=dyno      only show output from this dyno type (such as "web" or
                       "worker")

  -n, --num=num        number of lines to display

  -r, --remote=remote  git remote of app to use

  -s, --source=source  only show output from this source (such as "app" or
                       "heroku")

  -t, --tail           continually stream logs

  --force-colors       force use of colors (even on non-tty output)</i>
</pre>

To check your application logs you can use the logs command. You can filter by dyno type, edit the number of lines you want to see, continually stream logs etc.

<pre>
<b>heroku logs -n=4 -a name-of-your-app</b>

<i>2019-11-04T13:34:02.024374+00:00 heroku[web.1]: Restarting
2019-11-04T13:34:02.097510+00:00 heroku[web.1]: State changed from up to starting
2019-11-04T13:34:02.191176+00:00 heroku[worker.1]: Restarting
2019-11-04T13:34:02.264730+00:00 heroku[worker.1]: State changed from up to starting</i>
</pre>

# heroku pg:backups:capture [database]

<pre>
<b>OPTIONS</b>
  <i>-a, --app=app                  (required) app to run command against
  -r, --remote=remote            git remote of app to use
  -v, --verbose
  --wait-interval=wait-interval</i>
</pre>

To create a new database backup file, you can use this command. You have to enter the name of your database config variable (in this example it is HEROKU_POSTGRESQL_ORANGE_URL). You can find out the correct name for your database by checking the <b><i>heroku config</i></b> command. Then just enter the command like this:

<pre>
<b>heroku pg:backups:create HEROKU_POSTGRESQL_ORANGE_URL -a name-of-your-app</b>

 <i>▸    Continuous protection is already enabled for this database. Logical backups of large databases are likely to fail.
 ▸    See https://devcenter.heroku.com/articles/heroku-postgres-data-safety-and-continuous-protection#physical-backups-on-heroku-postgres.
Starting backup of add-on-name... done

Use Ctrl-C at any time to stop monitoring progress; the backup will continue running.
Use heroku pg:backups:info to check progress.
Stop a running backup with heroku pg:backups:cancel.

Backing up ORANGE to b002... done</i>
</pre>

To download you newly created backup, first check the backup_id:

<pre>
<b>heroku pg:backups -a name-of-your-app</b>

<i>=== Backups
ID    Created at                 Status                               Size      Database
────  ─────────────────────────  ───────────────────────────────────  ────────  ────────
b002  2019-11-04 13:56:58 +0000  Completed 2019-11-04 14:02:24 +0000  397.92MB  ORANGE</i>
</pre>

and then you can download it:

<pre>
<b>heroku pg:backups:download b002 -a name-of-your-app</b>

<i>Getting backup from ⬢ name-of-your-app... done, #2
Downloading latest.dump... ████████████████████████▏  100% 00:00 397.92MB</i>
</pre>

# heroku pg:bloat [database]

<pre>
<b>OPTIONS</b>
  <i>-a, --app=app        (required) app to run command against
  -r, --remote=remote  git remote of app to use</i>
</pre>

To show information about table and index bloat in your database, you can use this command:

<pre>
<b>heroku pg:bloat HEROKU_POSTGRESQL_ORANGE_URL -a name-of-your-app</b>

 <i>type  | schemaname |             object_name             | bloat |   waste    
-------+------------+-------------------------------------+-------+------------
 table | public     | table_1                             |   1.1 | 41 MB
 table | public     | table_2                             |   1.1 | 7360 kB
 table | public     | table_3                             |   1.1 | 4656 kB
 table | public     | table_4                             |   1.0 | 2480 kB</i>  
</pre>

The <b><i>bloat</i></b> column shows the bloat factor, which is the fraction of the original table that exists as bloat. Because it is a ratio, there are no units. The <b><i>waste</i></b> column shows the total bloat (in bytes) in each table and index in the system.

# heroku pg:psql [database]

<pre>
<b>OPTIONS</b>
  <i>-a, --app=app            (required) app to run command against
  -c, --command=command    SQL command to run
  -f, --file=file          SQL file to run
  -r, --remote=remote      git remote of app to use
  --credential=credential  credential to use</i>
</pre>

You can access a psql shell of your database this way:

<pre>
<b>heroku pg:psql HEROKU_POSTGRESQL_ORANGE_URL -a name-of-your-app</b>

<i>--> Connecting to add-on-name
psql (11.3, server 11.5 (Ubuntu 11.5-1.pgdg16.04+1))
SSL connection (protocol: TLSv1.2, cipher: cipher-code, bits: 256, compression: off)
Type "help" for help.

name-of-your-app::HEROKU_POSTGRESQL_ORANGE=></i>
</pre>

You can now query your database with standard SQL commands, do insert, update or delete statements if you need to.

# heroku pg:pull source target

<pre>
<b>OPTIONS</b>
  <i>-a, --app=app                            (required) app to run command against
  -r, --remote=remote                      git remote of app to use

  --exclude-table-data=exclude-table-data  tables for which data should be
                                           excluded (use ';' to split multiple
                                           names)</i>

<b>DESCRIPTION</b>
  <i>Pull from SOURCE into TARGET.

  TARGET must be one of:
     * a database name (i.e. on a local PostgreSQL server)  => TARGET must not
  exist and will be created
     * a fully qualified URL to a local PostgreSQL server   => TARGET must not
  exist and will be created
     * a fully qualified URL to a remote PostgreSQL server  => TARGET must exist
  and be empty</i>
</pre>

This command can come in handy if your local database is not big enough but you want to test some feature. This way, you can copy a staging/production database to a new local database:

<pre>
<b>heroku pg:pull HEROKU_POSTGRESQL_ORANGE_URL name_of_local_new_db -a name-of-your-app</b>

<i>heroku-cli: Pulling add-on-name ---> name_of_local_new_db
...
heroku-cli: Pulling complete.</i>
</pre>

You can also do the opposite, to push one of your local databases to Heroku, with **pg:push**.

# heroku pipelines:diff

<pre>
<b>OPTIONS</b>
  <i>-a, --app=app        (required) app to run command against
  -r, --remote=remote  git remote of app to use</i>
</pre>

If you want to check if your staging and production app are in sync, you can do so with the **pipelines:diff** command:

<pre>
<b>heroku pipelines:diff -a name-of-your-staging-app</b>

<i>Fetching apps from pipeline... done
Fetching release info for all apps... done

⬢ name-of-your-staging-app is up to date with ⬢ name-of-your-production-app</i>
</pre>

If they are not in sync, you will get a detailed commit diff with the differences:

<pre>
<b>heroku pipelines:diff -a name-of-your-staging-app</b>

<i>Fetching apps from pipeline... done
Fetching release info for all apps... done

=== ⬢ name-of-your-staging-app is ahead of ⬢ name-of-your-production-app by 2 commits
SHA      Date                  Author        Message
some-sha 2019-10-23T11:56:47Z  sinanmujan    Update Ruby version to 2.6.5
some-sha 2019-10-10T07:00:08Z  sinanmujan    Fix redirect middleware</i>
</pre>

# heroku ps

<pre>
<b>OPTIONS</b>
  <i>-a, --app=app        (required) app to run command against
  -r, --remote=remote  git remote of app to use
  --json               display as json</i>
</pre>

To get information about all the dynos in your application, their startup command and up time, you can do this:

<pre>
<b>heroku ps -a name-of-your-app</b>

<i>=== web (Standard-1X): jemalloc.sh bundle exec puma -C config/puma.rb (1)
web.1: up 2019/11/05 00:40:48 +0100 (~ 10h ago)

=== worker (Standard-1X): bundle exec sidekiq -e production -C config/sidekiq.yml (1)
worker.1: up 2019/11/04 17:44:06 +0100 (~ 17h ago)</i>
</pre>

# heroku ps:exec

<pre>
<b>OPTIONS</b>
  <i>-a, --app=app        (required) app to run command against
  -d, --dyno=dyno      specify the dyno to connect to
  -r, --remote=remote  git remote of app to use
  --ssh                use native ssh
  --status             lists the status of the SSH server in the dyno</i>
</pre>

If you want to connect to one of your dynos through SSH, you can do so like this:

<pre>
<b>heroku ps:exec -a name-of-your-app</b>

<i>Establishing credentials... done
Connecting to web.1 on ⬢ name-of-your-app...
~ $</i>
</pre>

# heroku redis:cli

<pre>
<b>OPTIONS</b>
  <i>-a, --app=app          (required) app to run command against
  -c, --confirm=confirm
  -r, --remote=remote    git remote of app to use</i>
</pre>

You can access the Redis resource of your application:

<pre>
<b>heroku redis:cli -a name-of-your-app</b>

<i>Connecting to redis-horizontal-35620 (REDIS_URL):
some-redis-url:20099></i>
</pre>

# Copy database between Heroku apps

If you want to copy the entire database from one Heroku application to another, you can do it this way:

<pre>
<b>heroku pg:copy source_app::source_db_name destination_db_name -a destination_app</b>
</pre>

# Copy ENV variables between Heroku apps

If you want to copy ENV variables between 2 Heroku apps, there is an easy way to do this. First, we need to copy the settings from the current app to a text file on your local machine:

<pre>
<b>heroku config -s -a existing-heroku-app > config.txt</b>
</pre>

Then you can add the contents of this config file to your new Heroku app:

<pre>
<b>cat config.txt | tr '\n' ' ' | xargs heroku config:set -a new-heroku-app</b>
</pre>

# Summary

These were just some interesting and hopefully helpful Heroku commands. You may find more useful tips and tricks in the official [Heroku documentation](https://devcenter.heroku.com/categories/reference).