diff --git a/cli/command/image/build.go b/cli/command/image/build.go index 637068a80f4b..601cb6938e53 100644 --- a/cli/command/image/build.go +++ b/cli/command/image/build.go @@ -11,6 +11,8 @@ import ( "os" "regexp" "runtime" + "strings" + "path/filepath" "github.com/docker/cli/cli" "github.com/docker/cli/cli/command" @@ -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): @@ -253,7 +263,7 @@ 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 { @@ -261,7 +271,7 @@ func runBuild(dockerCli command.Cli, options buildOptions) error { } } - // 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) diff --git a/cli/command/image/build/context.go b/cli/command/image/build/context.go index a98cd7b237e1..1d3011aff6bc 100644 --- a/cli/command/image/build/context.go +++ b/cli/command/image/build/context.go @@ -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 } @@ -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 }