将文件从Golang中的Docker映像中拉出到本地文件系统

I’m trying to figure out how I can use the Go client (http://godoc.org/github.com/moby/moby/client) to pull a file from a docker image at a specific version (tag)

I want to download the image and then copy a file from the image onto the local file system. I see a lot of commands for dealing with an image, but not how to access its contents. I do see ways to access a container’s contents.

I’m suspecting I would need to download the image, create a container with the image and finally copy the contents out of the container. Though if I could avoid creating a container, that would be preferred.

Does anyone know exactly how to do this? Code snippet would be appreciated.

Thanks!

You must start the container, copy the file and then remove the container... It's not really an expensive operation since the container isn't started anyway.

Here's a working example that copies a file from the specified image to standard output. The API is straightforward to follow:

https://gist.github.com/ricardobranco777/a3be772935dfb1a183e0831496925585

package main

import (
        "archive/tar"
        "fmt"
        "io"
        "io/ioutil"
        "os"

        "github.com/docker/docker/api/types"
        "github.com/docker/docker/api/types/container"
        "github.com/docker/docker/client"
        "golang.org/x/net/context"
)

func main() {
        if len(os.Args) != 3 {
                fmt.Fprintf(os.Stderr, "Usage: %s IMAGE FILE
", os.Args[0])
                os.Exit(1)
        }
        imageName := os.Args[1]
        filePath := os.Args[2]

        ctx := context.Background()
        cli, err := client.NewEnvClient()
        if err != nil {
                panic(err)
        }

        out, err := cli.ImagePull(ctx, imageName, types.ImagePullOptions{})
        if err != nil {
                panic(err)
        }
        defer out.Close()
        if _, err := ioutil.ReadAll(out); err != nil {
                panic(err)
        }

        info, err := cli.ContainerCreate(ctx, &container.Config{
                Image: imageName,
        }, nil, nil, "")
        if err != nil {
                panic(err)
        }

        tarStream, _, err := cli.CopyFromContainer(ctx, info.ID, filePath)
        if err != nil {
                panic(err)
        }
        tr := tar.NewReader(tarStream)
        if _, err := tr.Next(); err != nil {
                panic(err)
        }

        io.Copy(os.Stdout, tr)

        if err := cli.ContainerRemove(ctx, info.ID, types.ContainerRemoveOptions{}); err != nil {
                panic(err)
        }
}