Skip to content

Commit

Permalink
Local builder: Support shell out to docker build
Browse files Browse the repository at this point in the history
Signed-off-by: David Gageot <[email protected]>
  • Loading branch information
dgageot committed Jul 20, 2018
1 parent 18e6c4e commit 4f92d9c
Show file tree
Hide file tree
Showing 5 changed files with 57 additions and 16 deletions.
26 changes: 17 additions & 9 deletions examples/annotated-skaffold.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -62,27 +62,35 @@ build:
# This next section is where you'll put your specific builder configuration.
# Valid builders are `local`, `googleCloudBuild` and `kaniko.
# Defaults to `local: {}`
# Example

# Pushing the images can be skipped. If no value is specified, it'll default to
# `true` on minikube or Docker for Desktop, for even faster build and deploy cycles.
# `false` on other types of kubernetes clusters that require pushing the images.
# kaffold defers to your ~/.docker/config for authentication information.
# If you're using Google Container Registry, make sure that you have gcloud and
# docker-credentials-helper-gcr configured correctly.
#
# By default, the local builder connects to the Docker daemon with Go code to build
# images. If `useDockerCLI` is set, skaffold will simply shell out to the docker CLI.
# `useBuildkit` can also be set to activate the experimental BuildKit feature.
#
# local:
# Pushing the images can be skipped. If no value is specified, it'll default to
# `true` on minikube or Docker for Desktop, for even faster build and deploy cycles.
# `false` on other types of kubernetes clusters that require pushing the images.
# Skaffold defers to your ~/.docker/config for authentication information.
# If you're using Google Container Registry, make sure that you have gcloud and
# docker-credentials-helper-gcr configured correctly.
# skipPush: true
# skipPush: true
# useDockerCLI: false
# useBuildkit: false

# Docker artifacts can be built on Google Container Builder. The projectId then needs
# to be provided and the currently logged user should be given permissions to trigger
# new builds on GCB.
#
# googleCloudBuild:
# projectId: YOUR_PROJECT

# Docker artifacts can be built on a Kubernetes cluster with Kaniko.
# Sources will be sent to a GCS bucket whose name is provided.
# Kaniko also needs access to a service account to push the final image.
# See https://github.com/GoogleContainerTools/kaniko#running-kaniko-in-a-kubernetes-cluster
# Example
#
# kaniko:
# gcsBucket: k8s-skaffold
# pullSecret: /a/secret/path/serviceaccount.json
Expand Down
39 changes: 33 additions & 6 deletions pkg/skaffold/build/docker.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,9 @@ import (
"context"
"fmt"
"io"
"os"
"os/exec"
"path/filepath"

"github.com/GoogleContainerTools/skaffold/pkg/skaffold/docker"
"github.com/GoogleContainerTools/skaffold/pkg/skaffold/schema/v1alpha2"
Expand All @@ -31,12 +34,36 @@ import (
func (l *LocalBuilder) buildDocker(ctx context.Context, out io.Writer, workspace string, a *v1alpha2.DockerArtifact) (string, error) {
initialTag := util.RandomID()

err := docker.RunBuild(ctx, out, l.api, workspace, types.ImageBuildOptions{
Tags: []string{initialTag},
Dockerfile: a.DockerfilePath,
BuildArgs: a.BuildArgs,
CacheFrom: a.CacheFrom,
})
var err error
if l.cfg.UseDockerCLI || l.cfg.UseBuildkit {
absDockerfilePath := a.DockerfilePath
if !filepath.IsAbs(a.DockerfilePath) {
absDockerfilePath = filepath.Join(workspace, a.DockerfilePath)
}

args := []string{"build", workspace, "--file", absDockerfilePath, "-t", initialTag}
args = append(args, docker.GetBuildArgs(a)...)
for _, from := range a.CacheFrom {
args = append(args, "--cache-from", from)
}

cmd := exec.Command("docker", args...)
if l.cfg.UseBuildkit {
cmd.Env = append(os.Environ(), "DOCKER_BUILDKIT=1")
}
cmd.Stdout = out
cmd.Stderr = out

err = util.RunCmd(cmd)
} else {
err = docker.RunBuild(ctx, out, l.api, workspace, types.ImageBuildOptions{
Tags: []string{initialTag},
Dockerfile: a.DockerfilePath,
BuildArgs: a.BuildArgs,
CacheFrom: a.CacheFrom,
})
}

if err != nil {
return "", errors.Wrap(err, "running build")
}
Expand Down
3 changes: 3 additions & 0 deletions pkg/skaffold/build/local.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,8 @@ import (

// LocalBuilder uses the host docker daemon to build and tag the image
type LocalBuilder struct {
cfg *v1alpha2.LocalBuild

api docker.APIClient
localCluster bool
pushImages bool
Expand All @@ -54,6 +56,7 @@ func NewLocalBuilder(cfg *v1alpha2.LocalBuild, kubeContext string) (*LocalBuilde
}

return &LocalBuilder{
cfg: cfg,
kubeContext: kubeContext,
api: api,
localCluster: localCluster,
Expand Down
1 change: 1 addition & 0 deletions pkg/skaffold/build/local_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -182,6 +182,7 @@ func TestLocalRun(t *testing.T) {
for _, test := range tests {
t.Run(test.description, func(t *testing.T) {
l := LocalBuilder{
cfg: test.config,
api: test.api,
localCluster: test.localCluster,
}
Expand Down
4 changes: 3 additions & 1 deletion pkg/skaffold/schema/v1alpha2/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,9 @@ type BuildType struct {
// LocalBuild contains the fields needed to do a build on the local docker daemon
// and optionally push to a repository.
type LocalBuild struct {
SkipPush *bool `yaml:"skipPush"`
SkipPush *bool `yaml:"skipPush"`
UseDockerCLI bool `yaml:"useDockerCLI"`
UseBuildkit bool `yaml:"useBuildkit"`
}

// GoogleCloudBuild contains the fields needed to do a remote build on
Expand Down

0 comments on commit 4f92d9c

Please sign in to comment.