0

So I am trying to build a docker image with the Golang SDK, everything runs except the section in the Dockerfile where I use COPY to copy a file across into the image:

COPY testfile.txt /testfile.txt

My code is as follows:

func buildImage() {
    // Run in directory where Dockerfile is found
    os.Chdir("build-dir")

    cli, err := client.NewEnvClient()
    if err != nil {log.Fatal(err, " :unable to init client")}

    // Image Build requiresa tar file
    tar := new(archivex.TarFile)
    tar.Create("dockerfile.tar")
    tar.AddAll(".", true)
    tar.Close()

    // Use tar file as docker context
    dockerBuildContext, err := os.Open("dockerfile.tar")
    defer dockerBuildContext.Close()
    options := types.ImageBuildOptions{
        SuppressOutput: false,
        Remove:         true,
        ForceRemove:    true,
        PullParent:     true,
        Tags:           []string{"latest"},
        Dockerfile:     "Dockerfile",
    }
    buildResponse, err := cli.ImageBuild(context.Background(), dockerBuildContext, options)
    defer buildResponse.Body.Close()
    if err != nil {
        log.Fatal(err, " :unable to build docker image")
    }

    // Copy out response of stream
    _, err = io.Copy(os.Stdout, buildResponse.Body)


    if err != nil {
        log.Fatal(err, " :unable to read image build response")
    }
}

The code fails with:

{
    "errorDetail": {
        "message":"COPY failed: stat /var/lib/docker/tmp/docker-builder264844317/testfile.txt: no such file or directory"
    },
    "error":"COPY failed: stat /var/lib/docker/tmp/docker-builder264844317/testfile.txt: no such file or directory"
}

So far I have tried copying the files into the tar before building and then I have also tried moving the textfile.txt into the directory I run the command from but I still can not seem to get past this point

Extra information:

The file is in the same directory as the Dockerfile:

-- build-dir
   |-- Dockerfile
   |-- testfile.txt
Spazzy757
  • 889
  • 4
  • 20
  • Docker will look for the file `testfile.txt` from the root i.e. the place where you`Dockerfile` is kept. So make sure testfile and Dockerfile are on the same level. – Rash Mar 22 '19 at 13:47
  • It is on the same level (question updated to show) – Spazzy757 Mar 22 '19 at 13:52
  • Still, can you try this and see if that works - `COPY build-dir/testfile.txt /testfile.txt`? – Rash Mar 22 '19 at 13:59
  • I still get the same error – Spazzy757 Mar 22 '19 at 14:06
  • Strange. My doubt was from this line `tar.AddAll(".", true)` where you said to add all the files in the current directory. I assumed your tar program is not taking build-dir as your context root. Can you print out the value of `dockerBuildContext`? – Rash Mar 22 '19 at 14:16
  • A colleague just saw the same, my build context was missing the file i was trying to copy into the file – Spazzy757 Mar 22 '19 at 14:29
  • see this answer it really helped me: https://stackoverflow.com/a/51182726/9673980 – Bryan Neugebauer Sep 26 '19 at 07:25

2 Answers2

4

From Source

The docker build command builds Docker images from a Dockerfile and a “context”. A build’s context is the set of files located in the specified PATH or URL. The build process can refer to any of the files in the context. For example, your build can use a COPY instruction to reference a file in the context.

Docker build-context is the entire directory you send to the docker engine. While building your image, Docker engine will try to find the files from the root of your build-context.

In your case, the file was not added to the build-context.

Rash
  • 7,677
  • 1
  • 53
  • 74
1

So a colleague pointed out to me instead of just running just `tar.AddAll' i also need to specify the files I want to add, see updated code below:

func buildCIImage() {
    os.Chdir("ci-cd")
    cli, err := client.NewEnvClient()
    if err != nil {log.Fatal(err, " :unable to init client")}

    // open the file to pass into the tar
    file, err := os.OpenFile("testfile.txt", os.O_RDWR, os.ModePerm)
    // Used to get the files information
    fileInfo, err := os.Stat("testfile.txt")

    tar := new(archivex.TarFile)
    tar.Create("dockerfile.tar")
    tar.AddAll(".", true)

    // Add file into tar
    tar.Add("testfile.txt", file, fileInfo)
    tar.Close()
    dockerBuildContext, err := os.Open("dockerfile.tar")
    defer dockerBuildContext.Close()
    options := types.ImageBuildOptions{
        SuppressOutput: false,
        Remove:         true,
        ForceRemove:    true,
        PullParent:     true,
        Tags:           []string{"bootstrap"},
        Dockerfile:     "Dockerfile",
    }
    buildResponse, err := cli.ImageBuild(context.Background(), dockerBuildContext, options)
    defer buildResponse.Body.Close()
    if err != nil {
        log.Fatal(err, " :unable to build docker image")
    }
    _, err = io.Copy(os.Stdout, buildResponse.Body)
    if err != nil {
        log.Fatal(err, " :unable to read image build response")
    }
}
Spazzy757
  • 889
  • 4
  • 20