Buildpacks
Last updated December 05, 2024
Table of Contents
Buildpacks are a set of scripts that transform code into a deployable artifact with minimal configuration that gets executed on a dyno. Heroku implements its support for Ruby, Python, Java, Clojure, Node.js, Scala, Go, PHP, and .NET via a set of open-source buildpacks.
A typical buildpack performs operations like:
- Inspect your source code to detect the programming language and version
- Install programming language binaries
- Install dependencies
- Compile code
- Build frontend assets
- and more..
We maintain a collection of officially supported classic buildpacks for the Heroku Cedar generation of our platform, and Heroku Cloud Native Buildpacks for the Fir generation.
You can also deploy Docker images directly to Heroku Cedar instead of deploying code with git push
.
Classic Buildpacks
In Cedar, the slug compiler assembles the output from classic buildpacks into an executable slug.
Alternatively, you can manually create and deploy a slug via the platform API instead.
You can’t use classic buildpacks in Fir.
With classic buildpacks, you set the version of Heroku’s base image, for example, heroku-24
, with heroku stacks:set
.
Cloud Native Buildpacks
In Fir, Heroku supports the use of Cloud Native Buildpacks (CNBs). CNBs build an Open Container Initiative (OCI) image from your code. CNBs are only available in Fir.
See this short video introduction. For a deeper understanding of the concepts behind Cloud Native Buildpacks, see buildpacks.io’s official documentation.
Heroku Cloud Native Buildpacks
Heroku Cloud Native Buildpacks are CNBs designed to bring the same experience of our Cedar platform to Fir, and anywhere else that supports containers. Heroku CNBs produce a production-ready image for deployment to Heroku Fir.
All Fir-generation Heroku apps use CNBs by default. You can learn more about Heroku CNBs here. They are made available to Fir via the CNB builder, heroku/builder:24
, which you can also use locally with the Pack CLI.
With CNBs, the version of the Heroku base image used depends on the builder. If you want to use a different builder and base image than the default, you can change your project.toml
file.
The heroku stacks
CLI command is for managing apps that use classic buildpacks. While the value for stack
for classic buildpack apps is the version of its Heroku base image, for Cloud Native Buildpack apps, stack
always equals cnb
.
Compared to classic buildpacks, Heroku Cloud Native Buildpacks provide:
- Support for arm64 CPU architectures
- Compliance with open standards
- Compatibility with cloud native tooling
- Off-platform usability such as local build debugging and inspection
See Classic and Cloud Native Buildpacks Comparison.
Supported Buildpacks
Heroku maintains a collection of officially supported classic buildpacks and Heroku CNBs. See Officially Support Buildpacks for more info.
Third-Party Buildpacks
You can use custom buildpacks to support languages or frameworks not covered by Heroku’s officially supported buildpacks. See Using Third-Party Buildpacks for more info. Heroku doesn’t provide official support for custom buildpacks.
Buildpack Auto-Detection
When you deploy your code, we automatically detect the correct buildpack to use for your app when possible. Detection criteria depend on the language. For example, a Node buildpack looks for a package.json
file.
For apps using classic buildpacks, if the build succeeds, the detected buildpack is permanently set for future pushes to your application as if you had manually set the buildpack.
For apps using CNBs, auto-detection happens each time you deploy, unless the buildpacks are explicitly specified via project.toml.
Detection Failures
While Heroku can normally detect which buildpack to use for your app, there are some common causes of detection failure:
- Your app uses a language that isn’t supported by Heroku’s official buildpacks, such as Rust or Elixir.
- Your app is missing a critical file, such as package.json for Node.js apps or go.mod for Go apps.
In these cases, you can manually set a buildpack.
Buildpack Behavior
See each of our supported language’s docs category for articles describing the behavior of each buildpack on our platform. You can also click on the GitHub links listed in Officially Supported Buildpacks to read more about the buildpacks in each repo.
Managing Buildpacks
For many apps, the auto-detected buildpack is all you need.
You can manually add and remove buildpacks for your app. See Managing Buildpacks for more info.
There are many scenarios where you need multiple buildpacks for an application. See Using Multiple Buildpacks for an App for instructions. Typical scenarios include database connection pooling using PgBouncer, or asset handling using a Node.js library in combination with a Ruby, Python or PHP application.
Creating a Buildpack
To use a language or framework not yet supported on Heroku you can create a custom buildpack.
To get started with classic buildpacks, learn about their structure in Buildpack API.
For info on creating your own Cloud Native Buildpack, see buildpacks.io official documentation.
Troubleshooting
See Troubleshooting Buildpack Errors.
Limitations for Cloud Native Buildpacks
App config vars are unavailable for CNB builds on Heroku Fir. Without these environment variables, avoid private dependency installation at build time. Either vendor private dependencies into the repo, or avoid private dependencies.
You can set environment variables in project.toml
, but don’t use it for secrets. See Setting Config Vars for more information.