Skip Navigation
Show nav
Dev Center
  • Get Started
  • Documentation
  • Changelog
  • Search
  • Get Started
    • Node.js
    • Ruby on Rails
    • Ruby
    • Python
    • Java
    • PHP
    • Go
    • Scala
    • Clojure
    • .NET
  • Documentation
  • Changelog
  • More
    Additional Resources
    • Home
    • Elements
    • Products
    • Pricing
    • Careers
    • Help
    • Status
    • Events
    • Podcasts
    • Compliance Center
    Heroku Blog

    Heroku Blog

    Find out what's new with Heroku on our blog.

    Visit Blog
  • Log inorSign up
Hide categories

Categories

  • Heroku Architecture
    • Compute (Dynos)
      • Dyno Management
      • Dyno Concepts
      • Dyno Behavior
      • Dyno Reference
      • Dyno Troubleshooting
    • Stacks (operating system images)
    • Networking & DNS
    • Platform Policies
    • Platform Principles
  • Developer Tools
    • Command Line
    • Heroku VS Code Extension
  • Deployment
    • Deploying with Git
    • Deploying with Docker
    • Deployment Integrations
  • Continuous Delivery & Integration (Heroku Flow)
    • Continuous Integration
  • Language Support
    • Node.js
      • Working with Node.js
      • Troubleshooting Node.js Apps
      • Node.js Behavior in Heroku
    • Ruby
      • Rails Support
      • Working with Bundler
      • Working with Ruby
      • Ruby Behavior in Heroku
      • Troubleshooting Ruby Apps
    • Python
      • Working with Python
      • Background Jobs in Python
      • Python Behavior in Heroku
      • Working with Django
    • Java
      • Java Behavior in Heroku
      • Working with Java
      • Working with Maven
      • Working with Spring Boot
      • Troubleshooting Java Apps
    • PHP
      • PHP Behavior in Heroku
      • Working with PHP
    • Go
      • Go Dependency Management
    • Scala
    • Clojure
    • .NET
      • Working with .NET
  • Databases & Data Management
    • Heroku Postgres
      • Postgres Basics
      • Postgres Getting Started
      • Postgres Performance
      • Postgres Data Transfer & Preservation
      • Postgres Availability
      • Postgres Special Topics
      • Migrating to Heroku Postgres
    • Heroku Key-Value Store
    • Apache Kafka on Heroku
    • Other Data Stores
  • AI
    • Model Context Protocol
    • Vector Database
    • Working with AI
    • Heroku Inference
      • Quick Start Guides
      • AI Models
      • Inference Essentials
      • Inference API
  • Monitoring & Metrics
    • Logging
  • App Performance
  • Add-ons
    • All Add-ons
  • Collaboration
  • Security
    • App Security
    • Identities & Authentication
      • Single Sign-on (SSO)
    • Private Spaces
      • Infrastructure Networking
    • Compliance
  • Heroku Enterprise
    • Enterprise Accounts
    • Enterprise Teams
    • Heroku Connect (Salesforce sync)
      • Heroku Connect Administration
      • Heroku Connect Reference
      • Heroku Connect Troubleshooting
  • Patterns & Best Practices
  • Extending Heroku
    • Platform API
    • App Webhooks
    • Heroku Labs
    • Building Add-ons
      • Add-on Development Tasks
      • Add-on APIs
      • Add-on Guidelines & Requirements
    • Building CLI Plugins
    • Developing Buildpacks
    • Dev Center
  • Accounts & Billing
  • Troubleshooting & Support
  • Integrating with Salesforce
  • Heroku Architecture
  • Stacks (operating system images)
  • Heroku-20 Stack

Heroku-20 Stack

English — 日本語に切り替える

Last updated May 01, 2025

Table of Contents

  • What’s new
  • Available software
  • Support period
  • Using Heroku-20
  • Upgrading to Heroku-20
  • Heroku-20 Docker image

The Heroku-20 stack reached end-of-life on April 30th, 2025. 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 upon Ubuntu 20.04, and so reached end-of-life on April 30th, 2025. See the Heroku-20 End-Of-Life FAQ for more details.

Using Heroku-20

It is no longer possible to create new Heroku-20 apps, or to switch an existing app’s stack to Heroku-20. Please use a supported stack instead.

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:

  1. The runtime image (heroku/heroku:20), which is recommended over the build image for most workloads.
  2. 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.

Keep reading

  • Stacks (operating system images)

Feedback

Log in to submit feedback.

Upgrading to the Latest Stack Heroku-22 Stack

Information & Support

  • Getting Started
  • Documentation
  • Changelog
  • Compliance Center
  • Training & Education
  • Blog
  • Support Channels
  • Status

Language Reference

  • Node.js
  • Ruby
  • Java
  • PHP
  • Python
  • Go
  • Scala
  • Clojure
  • .NET

Other Resources

  • Careers
  • Elements
  • Products
  • Pricing
  • RSS
    • Dev Center Articles
    • Dev Center Changelog
    • Heroku Blog
    • Heroku News Blog
    • Heroku Engineering Blog
  • Twitter
    • Dev Center Articles
    • Dev Center Changelog
    • Heroku
    • Heroku Status
  • Github
  • LinkedIn
  • © 2025 Salesforce, Inc. All rights reserved. Various trademarks held by their respective owners. Salesforce Tower, 415 Mission Street, 3rd Floor, San Francisco, CA 94105, United States
  • heroku.com
  • Legal
  • Terms of Service
  • Privacy Information
  • Responsible Disclosure
  • Trust
  • Contact
  • Cookie Preferences
  • Your Privacy Choices