Custom Build Scripts
docker build is the common way to build container images, but there are others. Bazel, s2i, and ko support building images. Tilt supports these other tools with the function
custom_build instead of
Building an image with a custom build tool requires:
- Name of the image to build (as a ref, e.g.
- Command to run (e.g.
bazel build //frontend:imageor
- Files to watch (e.g.
['frontend', 'util', 'data.txt']). When a dependency changes, Tilt starts an update to build the image then apply the YAML.
A simple case (that just calls
docker build to build an image named
frontend from the directory
frontend) would look like
custom_build( 'frontend', 'docker build -t $EXPECTED_REF frontend', ['./frontend'], )
One piece of this needs more explanation:
Tilt always deploys with a digest, not a bare ref. (Instead of
gcr.io/company-name/frontend, Tilt injects
gcr.io/company-name/frontend:tilt-ffd9c2013b5bf5d4). Before explaining why (at the bottom of this document), let’s describe what this means for your Tiltfile and build script.
Because different build tools have different ergonomics, Tilt supports two modes:
- one-time tags via $EXPECTED_REF
- temporary refs
This mode is easy if your tool takes the destination of the image as an argument (e.g.
- Tiltfile sets a custom build command (e.g.
custom_build(..., 'docker build -t $EXPECTED_REF frontend')).
- Tilt sets a one-time ref as environment variable before executing the custom build command. (e.g.
- The custom build command builds the image and pushes to that ref (e.g. by reading
Other tools want to have an image ref hard-coded in configuration. They’ll build and push to the same place each time. Instead of having to change your tool, tell Tilt what tag the build image will have with
custom_build(..., tag='frontend:s2i'). After Tilt runs your build command, it will find this image and retag and push it with a unique ID.
Live Update and Other Features
docker_build supports other options. The most impactful is Live Update, which lets you update code in Kubernetes without doing a full image build.
custom_build supports this as well, using the same syntax.
custom_build supports most other options of
docker_build, and a few specific to non-Docker container builders. If you find an option you think should exist but doesn’t, let us know in the
#tilt channel in Kubernetes Slack.
Why Tilt uses One-Time Tags
This section describes for the curious why Tilt uses tags the way it does, instead of using a fixed reference. Kubernetes (and the OCI model generally) support multiple ways to reference an image:
gcr.io/company-name/frontend:username-devel. These tags can change as you upload new images to the same tag.
gcr.io/company-name/frontend. This is shorthand for the tag
latest, and changes even more frequently.
gcr.io/company-name/frontend:tilt-ffd9c2013b5bf5d4. The unique bit may be a Nonce or a digest of the contents. These don’t change once set (though technically they’re not write-protected).
Tilt only deploys One-Time references. Instead of pushing to
gcr.io/company-name/frontend and leaving the YAML as-is, Tilt retags the image and rewrites the container spec. This makes the Tilt experience more reliable. Deploying with a Tagged reference creates a race condition. Pods created at different times from the same definition may end up running different code as the reference is overwritten.
Tilt supports any container image builder via
For a more complex example, see the tutorial on how to use
custom_build to build images with Bazel.
For a complete listing of all the
custom_build parameters, see API reference.