Skip to content

Commit

Permalink
Allow Dockerfile from outside build-context
Browse files Browse the repository at this point in the history
Historically, the Dockerfile had to be insde the build-context, because it was
sent as part of the build-context.

moby/moby@3f6dc81
added support for passing the Dockerfile through stdin, in which case the
contents of the Dockerfile is injected into the build-context.

This patch uses the same mechanism for situations where the location of the
Dockerfile is passed, and its path is outside of the build-context.

Before this change:

    $ mkdir -p myproject/context myproject/dockerfiles && cd myproject
    $ echo "hello" > context/hello
    $ echo -e "FROM busybox\nCOPY /hello /\nRUN cat /hello" > dockerfiles/Dockerfile
    $ docker build --no-cache -f $PWD/dockerfiles/Dockerfile $PWD/context

    unable to prepare context: the Dockerfile (/Users/sebastiaan/projects/test/dockerfile-outside/myproject/dockerfiles/Dockerfile) must be within the build context

After this change:

    $ mkdir -p myproject/context myproject/dockerfiles && cd myproject
    $ echo "hello" > context/hello
    $ echo -e "FROM busybox\nCOPY /hello /\nRUN cat /hello" > dockerfiles/Dockerfile
    $ docker build --no-cache -f $PWD/dockerfiles/Dockerfile $PWD/context

    Sending build context to Docker daemon  2.607kB
    Step 1/3 : FROM busybox
     ---> 6ad733544a63
    Step 2/3 : COPY /hello /
     ---> 9a5ae1c7be9e
    Step 3/3 : RUN cat /hello
     ---> Running in 20dfef2d180f
    hello
    Removing intermediate container 20dfef2d180f
     ---> ce1748f91bb2
    Successfully built ce1748f91bb2

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
  • Loading branch information
thaJeztah committed Feb 18, 2018
1 parent a0044ba commit d36614a
Show file tree
Hide file tree
Showing 2 changed files with 16 additions and 6 deletions.
14 changes: 12 additions & 2 deletions cli/command/image/build.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@ import (
"os"
"regexp"
"runtime"
"strings"
"path/filepath"

"github.com/docker/cli/cli"
"github.com/docker/cli/cli/command"
Expand Down Expand Up @@ -206,6 +208,14 @@ func runBuild(dockerCli command.Cli, options buildOptions) error {
buildCtx, relDockerfile, err = build.GetContextFromReader(dockerCli.In(), options.dockerfileName)
case isLocalDir(specifiedContext):
contextDir, relDockerfile, err = build.GetContextFromLocalDir(specifiedContext, options.dockerfileName)
if err == nil && strings.HasPrefix(relDockerfile, ".."+string(filepath.Separator)) {
// Dockerfile is outside of build-context; read the Dockerfile and pass it as dockerfileCtx
dockerfileCtx, err = os.Open(relDockerfile)
if err != nil {
return errors.Errorf("unable to open Dockerfile: %v", err)
}
defer dockerfileCtx.Close()
}
case urlutil.IsGitURL(specifiedContext):
tempDir, relDockerfile, err = build.GetContextFromGitURL(specifiedContext, options.dockerfileName)
case urlutil.IsURL(specifiedContext):
Expand Down Expand Up @@ -253,15 +263,15 @@ func runBuild(dockerCli command.Cli, options buildOptions) error {
}
}

// replace Dockerfile if it was added from stdin and there is archive context
// replace Dockerfile if it was added from stdin or a file outside the build-context, and there is archive context
if dockerfileCtx != nil && buildCtx != nil {
buildCtx, relDockerfile, err = build.AddDockerfileToBuildContext(dockerfileCtx, buildCtx)
if err != nil {
return err
}
}

// if streaming and dockerfile was not from stdin then read from file
// if streaming and Dockerfile was not from stdin then read from file
// to the same reader that is usually stdin
if options.stream && dockerfileCtx == nil {
dockerfileCtx, err = os.Open(relDockerfile)
Expand Down
8 changes: 4 additions & 4 deletions cli/command/image/build/context.go
Original file line number Diff line number Diff line change
Expand Up @@ -167,6 +167,10 @@ func GetContextFromGitURL(gitURL, dockerfileName string) (string, string, error)
return "", "", err
}
relDockerfile, err := getDockerfileRelPath(absContextDir, dockerfileName)
if err == nil && strings.HasPrefix(relDockerfile, ".."+string(filepath.Separator)) {
return "", "", errors.Errorf("the Dockerfile (%s) must be within the build context", dockerfileName)
}

return absContextDir, relDockerfile, err
}

Expand Down Expand Up @@ -318,10 +322,6 @@ func getDockerfileRelPath(absContextDir, givenDockerfile string) (string, error)
return "", errors.Errorf("unable to get relative Dockerfile path: %v", err)
}

if strings.HasPrefix(relDockerfile, ".."+string(filepath.Separator)) {
return "", errors.Errorf("the Dockerfile (%s) must be within the build context", givenDockerfile)
}

return relDockerfile, nil
}

Expand Down

0 comments on commit d36614a

Please sign in to comment.