Heroku-20 Stack
Last updated October 23, 2024
Table of Contents
The Heroku-20 stack is deprecated and will reach end-of-life on April 30th, 2025. Please upgrade to a newer stack as soon as possible. See the Heroku-20 End-Of-Life FAQ for more details.
This article describes the Heroku-20 stack, based on Ubuntu 20.04. What is a stack?
What’s new
This stack is now based on Ubuntu 20.04, compared to Ubuntu 18.04 used in the Heroku-18 stack.
The python
command will now run Python version 3, as Python 2 has reached end-of-life status. Python 2 is still available under the python2
command, but is now only available during the build (and not at app runtime). Users may also use Python 3 explicitly by invoking python3
.
The availability of a python
command is a change from a standard installation of Ubuntu 20.04, which will only offer python2
and python3
aliases. The python-is-python3
package ensures that existing software that executes python
will be able to do so, but this requires the called Python code to be compatible with Python version 3.
This change of default for python
only affects customers who use Python for ancillary purposes such as scripting during app startup or at build time. Python apps using the official Heroku Python support (via the Python buildpack) always receive the exact Python version specified by the app’s codebase, which takes precedence over the python
command provided at the operating system level.
Available software
Every stack on Heroku supports different operating system packages and language runtime versions. This support is typically confined to software that was still actively developed by the respective maintainers at the time the stack was first released.
Language runtimes
For the most accurate information on supported language runtime versions, please check the individual language pages:
Buildpack | Shorthand | Runtime versions |
---|---|---|
Ruby | heroku/ruby |
Runtime versions |
Node.js | heroku/nodejs |
Runtime versions |
Python | heroku/python |
Runtime versions |
Java | heroku/java |
Runtime versions |
PHP | heroku/php |
Runtime versions |
Go | heroku/go |
Runtime versions |
Operating system packages
For a full list of operating system packages available on Heroku-20, please refer to article Ubuntu Packages on Heroku Stacks.
Support period
Heroku-20 is based on Ubuntu 20.04. It will be supported through April 2025. Learn more about Heroku’s stack update policy.
Using Heroku-20
Heroku-24 is currently the default stack for newly created apps.
You can specify a stack when creating an app:
$ heroku create --stack heroku-20
You may change the stack on an existing app; the next build performed will then use the new stack:
$ heroku stack:set heroku-20
If you are using app.json
, you should also specify the stack there to ensure that your Review Apps and Heroku CI runs use the same stack:
{
"stack": "heroku-20"
}
An existing app’s stack cannot be changed using app.json
. The stack specified is only applied to newly created apps that are a Review App, a Heroku CI test run app, or an app created using a Heroku Button.
Upgrading to Heroku-20
Please refer to the stack upgrading guide to understand the procedures to follow when upgrading to a new stack.
We recommend that you monitor your application closely after migrating an app to the new stack to ensure it’s performing correctly.
Upgrade notes
The python
program now points to Python 3
If your application’s code invokes the python
program e.g. for scripting purposes during build or at runtime, this will now execute Python 3, so the code you’re running this way must be compatible with Python 3. You may alternatively use the python2
program to temporarily use Python 2, but keep in mind that this version of Python is end-of-life and no longer maintained.
This change of default for python
only affects customers who use Python for ancillary purposes such as scripting during app startup or at build time. Python apps using the official Heroku Python support always receive the exact Python version specified by the app’s codebase, which takes precedence over the python
program provided at the operating system level.
The default OpenSSL configuration now requires use of newer TLS protocols and ciphers
The default Ubuntu 20.04 openssl
configuration now sets a minimum TLS protocol version of v1.2. This means that TLS v1.0 and v1.1 are no longer supported by clients using OpenSSL to make outbound requests. This may manifest in the form of OpenSSL “no protocols available
” errors if clients hardcode older protocol versions, or if servers do not support TLS v1.2 or higher. For apps using Python, an “[SSL] internal error
” error may be shown instead of the “no protocols available
” error.
In addition, the default OpenSSL security level (SECLEVEL
), was changed from level 1 to level 2. This prevents OpenSSL from using insecure ciphers/keys and may result in “sslv3 alert handshake failure
”, “wrong signature type
” or “dh key too small
” errors when connecting to servers that are running outdated/buggy software, or that have insecure configurations.
This change in OpenSSL configuration only affects outbound requests made by your application. TLS termination for inbound requests is handled by the Heroku Router, which is unaffected by the stack used by an app.
If you encounter OpenSSL related errors, first check to see if you can reproduce using curl
, in order to rule out issues with third-party clients. For example:
$ heroku run curl -I --ciphers DEFAULT@SECLEVEL=2 <URL>
If the curl command did not reproduce the error, then it’s likely there is a problem with the client/library used to make the connection from your application, such as it hardcoding an old TLS protocol version. Check whether there are newer versions of your application dependencies that fix the issue and if not, report the issue to the author of the library. The following dependencies are known to be incompatible:
keen
Python client prior to v0.7.0 (KeenClient-Python#161)postmark
Ruby client prior to v1.21.3 (postmark-gem#86)
If the curl command above did reproduce the error, it proves it’s not an issue with the specific client/library being used by your application. Next, try setting the OpenSSL security level back to 1, to confirm whether the default security level change was the cause:
$ heroku run curl -I --ciphers DEFAULT@SECLEVEL=1 <URL>
If this now succeeds, then it likely means the server is running running outdated or misconfigured software that doesn’t perform key/cipher negotiation correctly. Contact the third-party server owner to request that it be fixed.
Datadog buildpack compatibility
If you encounter build errors such as “Package 'libsensors4' has no installation candidate
” or “Unable to locate package libsnmp30
” and are using the Datadog buildpack, it is likely that your app is pinned to an old Datadog buildpack version, so does not have the compatibility fixes for Heroku-20. See heroku-buildpack-datadog#216 for more details.
Heroku-20 Docker image
Heroku-20 is available as two Docker images:
- The runtime image (
heroku/heroku:20
), which is recommended over the build image for most workloads. - The build image (
heroku/heroku:20-build
), which is larger as it includes development headers and toolchains. It is only recommended for customers that need to compile source code or dependencies.
Use the following command in your Dockerfile
to use Heroku-20 as your base image:
FROM heroku/heroku:20
To learn more about deploying Docker images, please refer to the Heroku Container Registry and Runtime documentation.