Last updated 08 September 2017
Table of Contents
Heroku Exec is currently in beta. If you have questions or feedback, please email us at email@example.com
Heroku Exec is a feature for creating secure TCP and SSH tunnels into a dyno. It allows for SSH sessions, port forwarding, remote debugging, and inspection with popular Java diagnostic tools.
You can add Heroku Exec to a Heroku application via the CLI by running:
$ heroku ps:exec
The first time you run this command, it enables the Heroku Exec feature flag, adds a custom buildpack to your app, and prompts you to redeploy your application by running:
$ git commit -m "Heroku Exec" --allow-empty $ git push heroku master
After your application has deployed, you can run the command again to connect to your web dyno:
$ heroku ps:exec Establishing credentials... done Connecting to web.1 on ⬢ your-app... ~ $
By default, Heroku Exec connects to your
web.1 dyno, but you can optionally specify a dyno:
$ heroku ps:exec --dyno=web.2 Establishing credentials... done Connecting to web.2 on ⬢ your-app... ~ $
If you run into problems connecting to a dyno, use the
--status flag to check the status of the Exec connection:
$ heroku ps:exec --status === limitless-savannah-19617 Heroku Exec status Dyno Proxy Status Dyno Status ───── ──────────── ─────────── web.1 running up web.2 running up
In addition to creating an interactive terminal session, the CLI can forward traffic on a local port to a port inside a dyno. In the following example, 9090 is both the local port and the dyno port:
$ heroku ps:forward 9090 Listening on 9090 and forwarding to web.1:9090...
Then connect your remote debugger, profiler, or even a browser to localhost:9090, and your requests will be routed through a secure socket to port 9090 in the dyno. To stop port forwarding, use
You can also use a local SOCKS proxy if you need to forward traffic on multiple ports. Start the proxy by running this command:
$ heroku ps:socks
With the proxy running, you can access any port inside the dyno. For example:
$ curl --socks5 localhost:1080 0.0.0.0:12345
Using Java debugging tools
The Heroku Exec buildpack automatically detects when your application is using the Heroku Java buildpack, and it enables a number of JDK tools. To use these tools, you must first install the Heroku CLI Java plugin by running:
$ heroku plugins:install heroku-cli-java
Then you can open a JConsole connection to a dyno by running this command locally:
$ heroku java:jconsole
The JConsole connection is routed through a secure SOCKS proxy created with SSH, which ensures that all traffic is encrypted. But JConsole will warn you that the connection is insecure because the JVM is not aware of the lower level encryption.
heroku help java for a list of more Java-related commands, such as:
When Heroku Exec is enabled, the default
JAVA_TOOL_OPTIONS environment variable will change to include options that enable JMX for all Java processes in your dyno. You can override this by manually setting
heroku config:set. This will disable commands like
heroku java:visualvm, which require JMX. But other commands such as
java:jmap will continue to work.
Many popular IDEs provide remote debugging capabilities through an SSH tunnel.
In all cases, you must first configure your application to enable remote debugging. For Node.js, you must add the
--debug=9090 option to the
node command that starts your app. For example, your
Procfile might look like this:
web: node --debug=9090 index.js
For Java applications, you must provide the
-agentlib option to configure the Java Debug Wire Protocol (JDWP). For example:
web: java -agentlib:jdwp=transport=dt_socket,server=y,address=9090,suspend=n -jar target/myapp.jar
In both cases, the port 9090 is arbitrary.
After you change your
Procfile and redeploy your app, you can start port forwarding with the Heroku Exec client:
$ heroku ps:forward 9090
Finally, connect your IDE or remote debugger to
For more information on specific vendors, please see the IDE documentation:
For most JetBrains products, including IntelliJ IDEA and WebStorm, select “Edit Configurations” and create a new “Remote” run configuration. Select port 9090 and localhost. Then start the configuration, set a break-point, and open your application.
Copying files from a dyno
To copy files from a dyno, run the following command on your local machine (not on the dyno):
$ heroku ps:copy filename
This copies the file in the dyno with the given name to a local file with the same name. You can use the
-o option to specify the name of the local file.
Enabling Docker support
If you’re packaging your app with Docker and deploying via the container registry, using Heroku Exec requires a few additional setup steps:
- Enable the Heroku Exec feature:
$ heroku features:enable runtime-heroku-exec
Ensure that your Docker image has both
opensshinstalled. Alternatively, you can use the Heroku-16 base image.
heroku-exec.shfile with the following code:
[ -z "$SSH_CLIENT" ] && source <(curl --fail --retry 3 -sSL "$HEROKU_EXEC_URL")
heroku-exec.sh file must live in
/app/.profile.d, even though your
WORKDIR can be different. Here’s an example of a Dockerfile command that adds the file to the correct directory:
ADD ./.profile.d /app/.profile.d
Introspecting one-off dynos
You can use Heroku Exec to access a port in a one-off dyno. This is particularly useful when launching your process with a debugging tool such as Pry enabled to exercise some code from a local browser. For example:
$ heroku run bash Running bash on ⬢ sushi... up, run.8955 $ echo $PORT 9090 $ bundle exec rails server
heroku ps:socks --dyno run.8955 or
heroku ps:forward 9090 --dyno run.8955 locally to access the server running in your dyno (the exact dyno name will vary). If your web server is running on a port other than 9090, you must provide that port number as an argument to the
heroku ps:forward command.
Disabling the feature
To disable the feature, run the following command:
$ heroku features:disable runtime-heroku-exec
Then optionally remove the Heroku Exec buildpack from your app by running:
$ heroku buildpacks:remove https://github.com/heroku/exec-buildpack
Using with the Heroku Maven plugin
Before you can use Heroku Exec with the Heroku Maven plugin, you must add the following plugin configuration in your
pom.xml (note the
<plugin> <groupId>com.heroku.sdk</groupId> <artifactId>heroku-maven-plugin</artifactId> <version>1.1.3</version> <configuration> <buildpacks> <buildpack>https://github.com/heroku/exec-buildpack</buildpack> <buildpack>jvm-common</buildpack> </buildpacks> </configuration> </plugin>
Then redeploy with
mvn heroku:deploy and run
heroku ps:exec or other commands described in this document.
Each Heroku Exec connection lasts a maximum of one hour. After an hour, you might need to reconnect. Additionally, Heroku Exec is not supported in Shield Private Spaces.
The SSH session created by Heroku Exec will not have the config vars set as environment variables (i.e.,
env in a session will not list config vars set by
Shield Private Spaces compatibility
Due to the high-compliance requirements of apps running in Shield Private Spaces, Heroku Exec is not supported.