Hi there!

This is the first part of the article about docker SDK. In the current article, we will see how with the help of golang it is possible to make pull and list docker images.

Docker pull

As usual, initialize the go module, load the docker SDK and create the main.go file

go mod init
go get github.com/docker/docker/client

Let’s create a PullImage method in which we will create a docker client using the client.NewClientWithOpts method, as arguments to this method we will pass client.FromEnv which will take the docker configuration from environment variables and client.WithAPIVersionNegotiation() which will automatically determine the available version docker API. Now with the help of the client and the method ImagePull you can download the desired docker image. In the ImagePull method you need to pass the context, the name of the docker image that can be downloaded, and types.ImagePullOptions{}. In ImagePullOptions, you can pass authorization data if you need to download the docker image. At the very end, call io.Copy(os.Stdout, out) to display the pull command result. In the main function, call PullImage to load the docker image.

package main

import (
    "context"
    "io"
    "os"
    "log"

    "github.com/docker/docker/api/types"
    "github.com/docker/docker/client"
)

func PullImage(imageName string) error {
    ctx := context.Background()
    dockerClient, err := client.NewClientWithOpts(client.FromEnv, client.WithAPIVersionNegotiation())

    if err != nil {
        return err
    }

    out, err := dockerClient.ImagePull(ctx, imageName, types.ImagePullOptions{})
    if err != nil {
        return err
    }
    defer out.Close()

    io.Copy(os.Stdout, out)
    return nil
}

func main() {
    err := PullImage("debian")
    if err != nil {
        log.Fatalln(err)
    }
}

Running we will see the result

{"status":"Pulling from library/debian","id":"latest"}
{"status":"Digest: sha256:b42494c466d101bf06038e959e2e5acd227e1251987e79528e7d8b1f4040deaf"}
{"status":"Status: Image is up to date for debian:latest"}

Docker list

Now let’s write a method for displaying the docker images list. To do this, create the method ListAllImages. As in the previous example, create a docker client. Next, you need a filter that can be used to display the docker image according to some criteria. Since I want to display all docker images, the filter will remain empty. Now we will call a method ImageList in which it is necessary to pass a context and structure ImageListOptions which has two fields All and Filters. In Filters we will pass the previously created filter, and in All we will specify false. If you set All to true, then all intermediate docker images will also be displayed. You can now print information about all containers in the loop.

package main

import (
    "context"
    "fmt"

    "github.com/docker/docker/api/types"
    "github.com/docker/docker/api/types/filters"
    "github.com/docker/docker/client"
)

func ListAllImages() error {
    ctx := context.Background()
    dockerClient, err := client.NewClientWithOpts(client.FromEnv, client.WithAPIVersionNegotiation())

    if err != nil {
        return err
    }

    filter := filters.NewArgs()

    images, err := dockerClient.ImageList(ctx, types.ImageListOptions{
        All:     false,
        Filters: filter,
    })

    if err != nil {
        return err
    }

    for _, i := range images {
        fmt.Println(i)
    }
    return nil
}

func main() {
    err := ListAllImages()
    if err != nil {
        log.Fatalln(err)
    }
}

As a result, we will see:

{-1 1623251330 sha256:c0a98e816f894adc33b1c39d87925a5979391bde533b38d6e6eb41326b904e65 map[maintainer:Sebastian Ramirez <tiangolo@gmail.com>]  [tiangolo/uvicorn-gunicorn-fastapi@sha256:f444216a887d0d4360edd5b69c78c1de530d0083a797176f9abf20f3f341b196] [tiangolo/uvicorn-gunicorn-fastapi:python3.8] -1 1014169179 1014169179}
{-1 1611933531 sha256:714c659c9f6f4a167fe294f9330387581007f1e86429d3460d1fc7bd7ee52ff7 map[]  [lambci/lambda@sha256:22e9fbb4df8270efcebed96905edf0244dd595a8d6250f24200ad558c0a201bc] [lambci/lambda:build-python3.8] -1 1962950336 1962950336}
{-1 1568356668 sha256:db427f282c433e8470846e3daddd3f666cfdbf85235ff66b3b6814d3840648f4 map[]  [selenoid/chrome@sha256:7be4763d02d4cd76c5081a4793485f9263ce4c25e56194b82567ecf597425f83] [selenoid/chrome:77.0] -1 891512369 891512369}

You can also display individual fields because the previous result is not easy to read. To do this in the loop, this call fmt.Println(i) can be replaced by fmt.Println(i.RepoTags, i.Size) and we get the following result:

[tiangolo/uvicorn-gunicorn-fastapi:python3.8] 1014169179
[lambci/lambda:build-python3.8] 1962950336
[selenoid/chrome:77.0] 891512369