PFS Buildpacks

This topic describes buildpacks and how they are used in PFS to build container images from source code.


When building a container image, whether it happens locally or on cluster, PFS uses Cloud Native Buildpacks.

Buildpacks are pluggable, modular tools that translate source code into OCI images. They offer a programmatic alternative to Dockerfiles for building images, enabling composition of fine grained, dedicated, pieces of logic.

Function Builder Composition

The function builder used by PFS is composed of the following buildpacks, grouped by invoker language.

Java group

Node group

Command group

Detection and Building

Buildpacks rely on a two-phase contract for building images:

  1. The “detect” phase first determines which buildpacks will participate in the build.
  2. During the “build” phase, each participating buildpack can act on the results of previous buildpacks, and contribute state to the next.

This mechanism is exploited for PFS functions as follows:

  • The presence of a pom.xml or build.gradle file will trigger compilation and building of an image for running a Java function.
  • A package.json file or an --artifact flag pointing to a .js file will build the image for running a JavaScript function.
  • An --artifact flag pointing to a file with execute permissions will generate an image for running a Command function.

Intelligent Caching

In addition to smart detection logic, buildpacks provide some extra benefits such as the ability to craft image layers in a way that allow intelligent caching and re-use.

When re-building a function, if some aspects of the source have not changed, then buildpacks can decide to re-use layers, thus shortening the build lifecyle.

As an example of such a mechanism, if the package-lock.json file capturing the exact versions of NPM dependencies of a javascript function hasn’t changed between builds, then the invocation of NPM is skipped altogether.

Day 2 Operations

Another benefit of buildpacks and their layered approach is the ability to patch images by replacing layers remotely, without impacting the behavior of the function.

This is especially important when security patches need to be applied to OS-level layers of hundreds of images at once.

More information can be found at the site.