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:

Currently, this only works with local and cluster build types.

Contract between Skaffold and Custom Build Script

Skaffold will pass in the following 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.
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.

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 locally, in addition to adding a custom field to each corresponding artifact in the build add cluster to you build config.

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 arguments passed to the docker build. It also accepts 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: gcr.io/k8s-skaffold/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
Last modified November 6, 2019: code review changes (579d01a32)