Build
Skaffold has native support for several different tools for building images:
- Dockerfile
- locally with Docker
- in-cluster with Kaniko
- on cloud with Google Cloud Build
- Jib Maven and Gradle
- locally
- on cloud with Google Cloud Build
- Bazel locally
- Custom script locally
- CNCF Buildpacks
The build
section in the Skaffold configuration file, skaffold.yaml
,
controls how artifacts are built. To use a specific tool for building
artifacts, add the value representing the tool and options for using that tool
to the build
section.
For a detailed discussion on Skaffold configuration, see Skaffold Concepts and skaffold.yaml References.
Dockerfile locally with Docker
If you have Docker installed, Skaffold can be configured to build artifacts with the local Docker daemon.
By default, Skaffold connects to the local Docker daemon using Docker Engine APIs, though it can also use the Docker command-line interface instead, which enables artifacts with BuildKit.
After the artifacts are successfully built, Docker images will be pushed to the remote registry. You can choose to skip this step.
Configuration
To use the local Docker daemon, add build type local
to the build
section
of skaffold.yaml
. The following options can optionally be configured:
Option | Description | Default |
---|---|---|
push |
should images be pushed to a registry. If not specified, images are pushed only if the current Kubernetes context connects to a remote cluster. |
|
useDockerCLI |
use docker command-line interface instead of Docker Engine APIs. |
false |
useBuildkit |
use BuildKit to build Docker images. | false |
Example
The following build
section instructs Skaffold to build a
Docker image gcr.io/k8s-skaffold/example
with the local Docker daemon:
build:
artifacts:
- image: gcr.io/k8s-skaffold/example
local: {}
Which is equivalent to:
build:
artifacts:
- image: gcr.io/k8s-skaffold/example
local:
useDockerCLI: false
useBuildkit: false
Dockerfile remotely with Google Cloud Build
Google Cloud Build is a Google Cloud Platform service that executes your builds using Google infrastructure. To get started with Google Build, see Cloud Build Quickstart.
Skaffold can automatically connect to Cloud Build, and run your builds with it. After Cloud Build finishes building your artifacts, they will be saved to the specified remote registry, such as Google Container Registry.
Skaffold Google Cloud Build process differs from the gcloud command
gcloud builds submit
. Skaffold will create a list of dependent files
and submit a tar file to GCB. It will then generate a single step cloudbuild.yaml
and will start the building process. Skaffold does not honor .gitignore
or .gcloudignore
exclusions. If you need to ignore files use .dockerignore
. Any cloudbuild.yaml
found will not
be used in the build process.
Configuration
To use Cloud Build, add build type googleCloudBuild
to the build
section of skaffold.yaml
. The following options can optionally be configured:
Option | Description | Default |
---|---|---|
projectId |
ID of your Cloud Platform Project. If it is not provided, Skaffold will guess it from the image name. For example, given the artifact image name gcr.io/myproject/image , Skaffold will use the myproject GCP project. |
|
diskSizeGb |
disk size of the VM that runs the build. See Cloud Build Reference. |
|
machineType |
type of the VM that runs the build. See Cloud Build Reference. |
|
timeout |
amount of time (in seconds) that this build should be allowed to run. See Cloud Build Reference. |
|
dockerImage |
image that runs a Docker build. See Cloud Builders. | gcr.io/cloud-builders/docker |
kanikoImage |
image that runs a Kaniko build. See Cloud Builders. | gcr.io/kaniko-project/executor |
mavenImage |
image that runs a Maven build. See Cloud Builders. | gcr.io/cloud-builders/mvn |
gradleImage |
image that runs a Gradle build. See Cloud Builders. | gcr.io/cloud-builders/gradle |
concurrency |
how many artifacts can be built concurrently. 0 means “no-limit” Defaults to 0. |
|
Example
The following build
section, instructs Skaffold to build a
Docker image gcr.io/k8s-skaffold/example
with Google Cloud Build:
build:
artifacts:
- image: gcr.io/k8s-skaffold/example
googleCloudBuild:
projectId: YOUR-GCP-PROJECT
Dockerfile in-cluster with Kaniko
Kaniko is a Google-developed open source tool for building images from a Dockerfile inside a container or Kubernetes cluster. Kaniko enables building container images in environments that cannot easily or securely run a Docker daemon.
Skaffold can help build artifacts in a Kubernetes cluster using the Kaniko image; after the artifacts are built, kaniko must push them to a registry.
Configuration
To use Kaniko, add build type kaniko
to the build
section of
skaffold.yaml
. The following options can optionally be configured:
Option | Description | Default |
---|---|---|
flags |
additional flags to be passed to Kaniko command line. See Kaniko Additional Flags. Deprecated - instead the named, unique fields should be used, e.g. buildArgs , cache , target . |
[] |
dockerfile |
locates the Dockerfile relative to workspace. | Dockerfile |
target |
Dockerfile target name to build. |
|
buildArgs |
arguments passed to the docker build. It also accepts environment variables via the go template syntax. | {} |
buildContext |
where the build context for this artifact resides. |
|
image |
Docker image used by the Kaniko pod. Defaults to the latest released version of gcr.io/kaniko-project/executor . |
|
cache |
configures Kaniko caching. If a cache is specified, Kaniko will use a remote cache which will speed up builds. |
|
reproducible |
used to strip timestamps out of the built image. | false |
skipTLS |
skips TLS verification when pulling and pushing the image. | false |
The buildContext
can be either:
Option | Description |
---|---|
gcsBucket |
GCS bucket to which sources are uploaded. Kaniko will need access to that bucket to download the sources. |
localDir |
configures how Kaniko mounts sources directly via an emptyDir volume. |
Since Kaniko builds images directly to a registry, it requires active cluster credentials.
These credentials are configured in the cluster
section with the following options:
Option | Description | Default |
---|---|---|
HTTP_PROXY |
for kaniko pod. |
|
HTTPS_PROXY |
for kaniko pod. |
|
pullSecret |
path to the Google Cloud service account secret key file. |
|
pullSecretName |
name of the Kubernetes secret for pulling the files from the build context and pushing the final image. If given, the secret needs to contain the Google Cloud service account secret key under the key kaniko-secret . |
kaniko-secret |
pullSecretMountPath |
path the pull secret will be mounted at within the running container. |
|
namespace |
Kubernetes namespace. Defaults to current namespace in Kubernetes configuration. |
|
timeout |
amount of time (in seconds) that this build is allowed to run. Defaults to 20 minutes (20m ). |
|
dockerConfig |
describes how to mount the local Docker configuration into a pod. |
|
resources |
define the resource requirements for the kaniko pod. |
|
concurrency |
how many artifacts can be built concurrently. 0 means “no-limit” Defaults to 0. |
|
To set up the credentials for Kaniko refer to the kaniko docs.
The recommended way is to store the pull secret in Kubernetes and configure pullSecretName
.
Alternatively, the path to a credentials file can be set with the pullSecret
option:
build:
cluster:
pullSecretName: pull-secret-in-kubernetes
# OR
pullSecret: path-to-service-account-key-file
Similarly, when pushing to a docker registry:
build:
cluster:
dockerConfig:
path: ~/.docker/config.json
# OR
secretName: docker-config-secret-in-kubernetes
Note that the Kubernetes secret must not be of type kubernetes.io/dockerconfigjson
which stores the config json under the key ".dockerconfigjson"
, but an opaque secret with the key "config.json"
.
Example
The following build
section, instructs Skaffold to build a
Docker image gcr.io/k8s-skaffold/example
with Kaniko:
build:
artifacts:
- image: gcr.io/k8s-skaffold/example
kaniko:
buildContext:
gcsBucket: YOUR-BUCKET
cluster:
pullSecretName: YOUR-PULL-SECRET-NAME
Jib Maven and Gradle locally
Jib is a set of plugins for Maven and Gradle for building optimized OCI-compliant container images for Java applications without a Docker daemon.
Skaffold can help build artifacts using Jib; Jib builds the container images and then pushes them to the local Docker daemon or to remote registries as instructed by Skaffold.
Skaffold requires using Jib v1.4.0 or later.
Configuration
To use Jib, add a jib
field to each artifact you specify in the
artifacts
part of the build
section. context
should be a path to
your Maven or Gradle project.
Note
Your project must be configured to use Jib already.The jib
type offers the following options:
Option | Description | Default |
---|---|---|
project |
selects which sub-project to build for multi-module builds. |
|
args |
additional build flags passed to the builder. | [] |
Skaffold’s jib support chooses the underlying builder (Maven or Gradle)
based on the presence of standard build files in the artifact
’s
context
directory:
- Maven:
pom.xml
, or.mvn
directory. - Gradle:
build.gradle
,gradle.properties
,settings.gradle
, or the Gradle wrapper script (gradlew
,gradlew.bat
, orgradlew.cmd
).
Example
See the Skaffold-Jib demo project for an example.
Multi-Module Projects
Skaffold can be configured for multi-module projects too. A multi-module project has several modules (Maven terminology) or sub-projects (Gradle terminology) that each produce a separate container image.
Maven
To build a Maven multi-module project, first identify the sub-projects (also called modules in Maven) that should produce a container image. Then for each such sub-project:
- Create a Skaffold
artifact
in theskaffold.yaml
. - Set the
artifact
’scontext
field to the root project location. - Add a
jib
element and set itsproject
field to the sub-project’s:artifactId
,groupId:artifactId
, or the relative path to the sub-project within the project.
Updating from earlier versions
Skaffold had required Maven multi-module projects bind a Jibbuild
or dockerBuild
goal to the package phase. These bindings are
no longer required with Jib 1.4.0 and should be removed.
Gradle
To build a multi-module project with Gradle, first identify the sub-projects that should produce a container image. Then for each such sub-project:
- Create a Skaffold
artifact
in theskaffold.yaml
. - Set the
artifact
’scontext
field to the root project location. - Add a
jib
element and set itsproject
field to the sub-project’s name (the directory, by default).
Jib Maven and Gradle remotely with Google Cloud Build
Bazel locally
Bazel is a fast, scalable, multi-language, and extensible build system.
Skaffold can help build artifacts using Bazel; after Bazel finishes building container images, they will be loaded into the local Docker daemon.
Configuration
To use Bazel, bazel
field to each artifact you specify in the
artifacts
part of the build
section, and use the build type local
.
context
should be a path containing the bazel files
(WORKSPACE
and BUILD
). The following options can optionally be configured:
Option | Description | Default |
---|---|---|
target |
Required bazel build target to run. |
|
args |
additional args to pass to bazel build . |
[] |
Not any Bazel target can be used
The target specified must produce a bundle compatible with docker load. See https://github.com/bazelbuild/rules_docker#using-with-docker-locallyExample
The following build
section instructs Skaffold to build a
Docker image gcr.io/k8s-skaffold/example
with Bazel:
build:
artifacts:
- image: gcr.io/k8s-skaffold/example
bazel:
target: //:example.tar
Custom Build Script Run Locally
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 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:
- Build and tag the
$IMAGE
image - 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.
Additional Environment Variables
Skaffold will pass in the following additional environment variables for the following builders:
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. |
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 use a custom build script, add a custom
field to each corresponding artifact in the build
section of the skaffold.yaml.
Currently, this only works with the local
and cluster
build types. 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.
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
Getting 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"]
Custom Build Scripts and 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.
Custom Build Scripts and 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
images=$(echo $IMAGES | tr " " "\n")
for image in $images
do
docker tag bazel:skaffold_example $image
if $PUSH_IMAGE
then
docker push $image
fi
done