Version v1.39 of the documentation is no longer actively maintained. The site that you are currently viewing is an archived snapshot. For up-to-date documentation, see the latest version.

Custom Build Script  beta 

Custom build scripts allow Skaffold users the flexibility to build artifacts with any builder they desire. Users can write a custom build script which must abide by the following contract for Skaffold to work as expected:

Contract between Skaffold and Custom Build Script

Skaffold will pass in the following additional environment variables to the custom build script:

Environment Variable Description Expectation
$IMAGE The fully qualified image name. For example, “gcr.io/image1:tag” The custom build script is expected to build this image and tag it with the name provided in $IMAGE. The image should also be pushed if $PUSH_IMAGE=true.
$PUSH_IMAGE Set to true if the image in $IMAGE is expected to exist in a remote registry. Set to false if the image is expected to exist locally. The custom build script will push the image $IMAGE if $PUSH_IMAGE=true
$BUILD_CONTEXT An absolute path to the directory this artifact is meant to be built from. Specified by artifact context in the skaffold.yaml. None.
$PLATFORMS A comma-separated string of platforms to build the image for. For example, linux/arm64,linux/amd64. If there’s only a single platform specified the custom build script should build for that platform. If multiple platforms are specified then the custom build script should build a multi-arch image comprising all those platforms.
$SKIP_TEST Whether to skip the tests after building. None.
Local environment variables The current state of the local environment (e.g. $HOST, $PATH). Determined by the golang os.Environ function. None.

As described above, the custom build script is expected to:

  1. Build and tag the $IMAGE image
  2. Push the image if $PUSH_IMAGE=true

Once the build script has finished executing, Skaffold will try to obtain the digest of the newly built image from a remote registry (if $PUSH_IMAGE=true) or the local daemon (if $PUSH_IMAGE=false). If Skaffold fails to obtain the digest, it will error out.

Configuration

To use a custom build script, add a custom field to each corresponding artifact in the build section of the skaffold.yaml. Supported schema for custom includes:

Option Description
buildCommand command executed to build the image.
dependencies file dependencies that skaffold should watch for both rebuilding and file syncing for this artifact.

buildCommand is required and points Skaffold to the custom build script which will be executed to build the artifact. The Go templates syntax can be used to inject environment variables into the build command. For example: buildCommand: ./build.sh --flag={{ .SOME_FLAG }} will replace {{ .SOME_FLAG }} with the value of the SOME_FLAG environment variable.

Artifact Dependency

You can define dependency on other artifacts using the requires keyword. Skaffold will provide each required artifact’s built image as an environment variable keyed on the alias field that can be referenced directly in the build script.

build:
  artifacts:
  - image: image1
    custom:
      # environment variable $IMG2 will be set to the build of image2
      buildCommand: |
        cat <<EOF | docker build --tag=$IMAGE --build-arg $IMG2 -
        FROM busybox
        ARG IMG2
        RUN echo 'Got ARG IMG2=$IMG2'
        EOF
    requires:
    - image: image2
      alias: IMG2
  - image: image2
    custom:
      buildCommand: echo 'FROM busybox' | docker build --tag=$IMAGE -

Custom Build Script Locally

In addition to these environment variables Skaffold will pass in the following additional environment variables for local builder:

Environment Variable Description Expectation
Docker daemon environment variables Inform the custom builder of which docker daemon endpoint we are using. Allows custom build scripts to work with tools like Minikube. For Minikube, this is the output of minikube docker-env. None.

Configuration

To configure custom build script locally, in addition to adding a custom field to each corresponding artifact in the build add local to you build config.

Custom Build Script in Cluster

In addition to these environment variables Skaffold will pass in the following additional environment variables for cluster builder:

Environment Variable Description Expectation
$KUBECONTEXT The expected kubecontext in which the image will be built. None.
$NAMESPACE The expected namespace in which the image will be built. None.
$PULL_SECRET_NAME The name of the secret with authentication required to pull a base image/push the final image built on cluster. None.
$DOCKER_CONFIG_SECRET_NAME The secret containing any required docker authentication for custom builds on cluster. None.
$TIMEOUT The amount of time an on cluster build is allowed to run. None.

Configuration

To configure custom build script in cluster, in addition to adding a custom field to each corresponding artifact in the build, add cluster to your build config.

Custom Build Script on Google Cloud Build

This configuration is currently not supported.

Dependencies for a Custom Artifact

dependencies tells the skaffold file watcher which files should be watched to trigger rebuilds and file syncs. Supported schema for dependencies includes:

Option Description Default
dockerfile should be set if the artifact is built from a Dockerfile, from which skaffold can determine dependencies.
command represents a custom command that skaffold executes to obtain dependencies. The output of this command must be a valid JSON array.
paths should be set to the file dependencies for this artifact, so that the skaffold file watcher knows when to rebuild and perform file synchronization. []
ignore specifies the paths that should be ignored by skaffold’s file watcher. If a file exists in both paths and in ignore, it will be ignored, and will be excluded from both rebuilds and file synchronization. Will only work in conjunction with paths. []

Paths and Ignore

Paths and Ignore are arrays used to list dependencies. Any paths in Ignore will be ignored by the skaffold file watcher, even if they are also specified in Paths. Ignore will only work in conjunction with Paths, and with none of the other custom artifact dependency types.

custom:
  buildCommand: ./build.sh
  dependencies:
    paths:
    - pkg/**
    - src/*.go
    ignore:
    - vendor/**

Dockerfile

Skaffold can calculate dependencies from a Dockerfile for a custom artifact. Passing in the path to the Dockerfile and any build args, if necessary, will allow skaffold to do dependency calculation.

Option Description Default
path locates the Dockerfile relative to workspace.
buildArgs key/value pairs used to resolve values of ARG instructions in a Dockerfile. Values can be constants or environment variables via the go template syntax. {}
custom:
  buildCommand: ./build.sh
  dependencies:
    dockerfile:
      path: path/to/Dockerfile
      buildArgs:
        file: foo

Dependencies from a command

Sometimes you might have a builder that can provide the dependencies for a given artifact. For example bazel has the bazel query deps command. Custom artifact builders can ask Skaffold to execute a custom command, which Skaffold can use to get the dependencies for the artifact for file watching.

The command must return dependencies as a JSON array, otherwise skaffold will error out.

For example, the following configuration is valid, as executing the dependency command returns a valid JSON array.

custom:
  buildCommand: ./build.sh
  dependencies:
    command: echo ["file1","file2","file3"]

File Sync

Syncable files must be included in both the paths section of dependencies, so that the skaffold file watcher knows to watch them, and the sync section, so that skaffold knows to sync them.

Logging

STDOUT and STDERR from the custom build script will be redirected and displayed within skaffold logs.

Example

The following build section instructs Skaffold to build an image gcr.io/k8s-skaffold/example with a custom build script build.sh:

build:
  artifacts:
    - image: example
      custom:
        buildCommand: ./build.sh
        dependencies:
          paths:
            - .
          ignore:
            - README*

A sample build.sh file, which builds an image with bazel and docker:

#!/bin/bash

bazel build //:skaffold_example.tar
TAR_PATH=$(bazel info bazel-bin)
docker load -i $TAR_PATH/skaffold_example.tar

image=$(echo $IMAGE)

if [ ! -z "$image" ]; then
  pack build $image
  if $PUSH_IMAGE
  then
    docker push $image
  fi
fi