Buildpack Scripts

A buildpack repository may contain the following five scripts in the bin directory:

bin/detect determines whether or not to apply the buildpack to an app.

bin/supply provides dependencies for an app.

bin/finalize prepares the app for launch.

bin/release provides feedback metadata to Cloud Foundry indicating how the app should be executed.

bin/compile is a deprecated alternative to bin/supply and bin/finalize.

The bin/supply and bin/finalize scripts replace the deprecated bin/compile script.
Older buildpacks may still use bin/compile with the latest version of Cloud Foundry. In this case, applying multiple buildpacks to a single app is not supported.
Similarly, newer buildpacks may still provide bin/compile for compatibility with Heroku and older versions of Cloud Foundry.

The bin/supply script is required for non-final buildpacks. The bin/finalize (or bin/compile) script is required for final buildpacks.

Note: In this document, the terms non-final buildpack and final buildpack, or last buildpack, are used to describe the process of applying multiple buildpacks to an app. See the following example: cf push APP-NAME -b FIRST-BUILDPACK -b SECOND-BUILDPACK -b FINAL-BUILDPACK.

Note: If you use only one buildpack for your app, this buildpack behaves as a final, or last, buildpack.

Note: When using multi-buildpack support, the last buildpack in order is the final buildpack, and is able to make changes to the app and determine a start command. All other specified buildpacks are non-final and only supply dependencies.

bin/detect

The detect script determines whether or not to apply the buildpack to an app. The script is called with one argument, the build directory for the app. The build directory contains the app files uploaded when a user performs a cf push.

The detect script returns an exit code of 0 if the buildpack is compatible with the app. In the case of system buildpacks, the script also prints the buildpack name, version, and other information to STDOUT.

The following is an example detect script that checks for a Ruby app based on the existence of a Gemfile:

Optionally, the buildpack detect script can output additional details provided by the buildpack developer. This includes buildpack versioning information and a list of configured frameworks and their associated versions.

The following is an example of the detailed information returned by the Java buildpack:

bin/supply

The supply script provides dependencies for the app and runs for all buildpacks. All output sent to STDOUT is relayed to the user through the Cloud Foundry Command Line Interface (cf CLI).

The script is run with four arguments:

The build directory for the app

The cache directory, which is a location the buildpack can use to store assets during the build process

The deps directory, which is where dependencies provided by all buildpacks are installed

The index, which is a number that represents the ordinal position of the buildpack

The supply script stores dependencies in deps/index. It may also look in other directories within deps to find dependencies supplied by other buildpacks.

The supply script must not modify anything outside of the deps/index directory. Staging may fail if such modification is detected.

The cache directory provided to the supply script of the final buildpack is preserved even when the buildpack is upgraded or otherwise changes. The finalize script also has access to this cache directory.

The cache directories provided to the supply scripts of non-final buildpacks are cleared if those buildpacks are upgraded or otherwise change.

bin/finalize

The finalize script prepares the app for launch and runs only for the last buildpack. All output sent to STDOUT is relayed to the user through the cf CLI.

The script is run with four arguments:

The build directory for the app

The cache directory, which is a location the buildpack can use to store assets during the build process

The deps directory, which is where dependencies provided by all buildpacks are installed

The index, which is a number that represents the ordinal position of the buildpack

The finalize script may find dependencies installed by the supply script of the same buildpack in deps/index. It may also look in other directories within deps to find dependencies supplied by other buildpacks.

The cache directory provided to the finalize script is preserved even when the buildpack is upgraded or otherwise changes. The supply script of the same buildpack also has access to this cache directory.

bin/compile (Deprecated)

The compile script is deprecated. It encompasses the behavior of the supply and finalize scripts for single buildpack apps by using the build directory to store dependencies.

The script is run with two arguments:

The build directory for the app

The cache directory, which is a location the buildpack can use to store assets during the build process

During the execution of the compile script, all output sent to STDOUT is relayed to the user through the cf CLI.

bin/release

The release script provides feedback metadata to Cloud Foundry indicating how the app should be executed. The script is run with one argument, the build directory. The script must generate a YAML file in the following format:

default_process_types:web:start_command.filetype

default_process_types indicates the type of app being run and the command used to start it.
This start command is used if a start command is not specified in the cf push or in a Procfile.

At this time, only the web type of apps is supported.

Note: To define environment variables for your buildpack, add a Bash script to the .profile.d directory in the root folder of your app.

The following example shows what a release script for a Rack app might return:

Droplet Filesystem

The buildpack staging process extracts the droplet into the /home/vcap directory inside the instance container and creates the following filesystem tree:

app/
deps/
logs/
tmp/
staging_info.yml

The app directory includes the contents of the build directory, and staging_info.yml contains the staging metadata saved in the droplet.

Buildpack Detection

When you push an app, Cloud Foundry uses a detection process to determine a single buildpack to use.
For general information about this process, see How Applications Are Staged.

During staging, each buildpack has a position in a priority list. You can retrieve this position by running cf buildpacks.

Cloud Foundry checks if the buildpack in position 1 is a compatible buildpack. If the position 1 buildpack is not compatible, Cloud Foundry moves on to the buildpack in position 2. Cloud Foundry continues this process until the correct buildpack is found.

If no buildpack is compatible, the cf push command fails with the following error:

For a more detailed account of how Cloud Foundry interacts with the buildpack, see the Sequence of Interactions section below.

Sequence of Interactions

This section describes the sequence of interactions between the Cloud Foundry platform and the buildpack. The sequence of interactions differs depending on whether the platform skips or performs buildpack detection.

No Buildpack Detection

Cloud Foundry skips buildpack detection if the developer specifies one or more buildpacks in the app manifest or in the cf push APP-NAME -b BUILDPACK-NAME cf CLI command.

If you explicitly specify buildpacks, Cloud Foundry performs the following interactions:

For each buildpack except the last buildpack, the platform does the following:

Creates the deps/index directory

Runs /bin/supply with the build, cache, and deps directories and the buildpack index

Accepts any modification of the deps/index directory

Accepts any modification of the cache directory

May disallow modification of any other directories

For the last buildpack, the platform does the following:

If /bin/finalize is present:

Creates the deps/index directory if it does not exist

If /bin/supply is present, runs /bin/supply with the build, cache, and deps directories and the buildpack index

Accepts any modification of the deps/index directory

May disallow modification of the build directory

Runs /bin/finalize with the build, cache, and deps directories and the buildpack index

Accepts any modification of the build directory

If /bin/finalize is not present:

Runs /bin/compile with the build and cache directories

Accepts any modification of the build directory

Runs /bin/release to determine staging information

At the end of this process, the deps directory is included at the root of the droplet, adjacent to the app directory.

Buildpack Detection

Cloud Foundry performs buildpack detection if the developer does not specify one or more buildpacks in the app manifest or in the cf push APP-NAME -b BUILDPACK-NAME cf CLI command.

Note: Cloud Foundry detects only one buildpack to use with the app.

If the platform performs detection, it does the following:

Runs /bin/detect for each buildpack

Selects the first buildpack with a /bin/detect script that returns a zero exit status

If /bin/finalize is present:

Creates the deps/index directory if it does not exist

If /bin/supply is present, runs /bin/supply with the build, cache, and deps directories and the buildpack index

Accepts any modification of the deps/index directory

May disallow modification of the build directory

Runs /bin/finalize on the build, cache, and deps directories

Accepts any modification of the build directory

If /bin/finalize is not present:

Runs /bin/compile on the build and cache directories

Accepts any modification of the build directory

Runs /bin/release to determine staging information

At the end of this process, the deps directory is included at the root of the droplet, adjacent to the app directory.