Когда вы решите написать, свой велосипед по ловле хуков из docker hub или из registry для автоматического обновления/запуска контейнеров на сервере, вам может пригодиться Docker Cli, который поможет управлять демоном Docker в вашей системе.

Для работы понадобится Go версии не ниже 1.9.4
Если вы все еще не перешли на модули установите Cli следующей командой:
go get github.com/docker/docker/client
Запуск контейнера
Следующий пример показывает как запустить контейнер с помощью Docker API. В коммандной строке вы бы использовали команду docker run, но мы без труда справимся с этой задачей в нашем сервисе.
Этот пример эквивалентен запуску команды docker run alpine echo hello world
package main { ctx := context.Background() cli, err := client.NewEnvClient() if err != nil { panic(err) } // Делаем docker pull reader, err := cli.ImagePull(ctx, "docker.io/library/alpine", types.ImagePullOptions{}) if err != nil { panic(err) } io.Copy(os.Stdout, reader) hostBinding := nat.PortBinding{ HostIP: "0.0.0.0", HostPort: "8000", } containerPort, err := nat.NewPort("tcp", "80") if err != nil { panic("Unable to get the port") } portBinding := nat.PortMap{containerPort: []nat.PortBinding{hostBinding}} // Создаем контейнер с заданной конфигурацией resp, err := cli.ContainerCreate(ctx, &container.Config{ Image: "alpine", Cmd: []string{"echo", "hello world"}, Tty: true, }, &container.HostConfig{ PortBindings: portBinding, }, nil, "") if err != nil { panic(err) } // Запускаем контейнер if err := cli.ContainerStart(ctx, resp.ID, types.ContainerStartOptions{}); err != nil { panic(err) } // Получаем логи контейнера out, err := cli.ContainerLogs(ctx, resp.ID, types.ContainerLogsOptions{ShowStdout: true}) if err != nil { panic(err) } io.Copy(os.Stdout, out) }
Получение списка запущенных контейнеров
Этот пример эквивалентен запуску команды docker ps
package main import ( "context" "fmt" "github.com/docker/docker/api/types" "github.com/docker/docker/client" ) func main() { cli, err := client.NewEnvClient() if err != nil { panic(err) } // Получение списка запуцщенных контейнеров(docker ps) containers, err := cli.ContainerList(context.Background(), types.ContainerListOptions{}) if err != nil { panic(err) } // Вывод всех идентификаторов контейнеров for _, container := range containers { fmt.Println(container.ID) } }
Остановка всех запущенных контейнеров
После того как вы научились создавать и запускать контейнеры, пришло время научиться управлять ими. Следующий пример остановит все запущенные контейнеры.
Не запускайте этот код на продакшн сервере!
package main import ( "context" "fmt" "github.com/docker/docker/api/types" "github.com/docker/docker/client" ) func main() { ctx := context.Background() cli, err := client.NewEnvClient() if err != nil { panic(err) } // Получение списка запуцщенных контейнеров(docker ps) containers, err := cli.ContainerList(ctx, types.ContainerListOptions{}) if err != nil { panic(err) } for _, c := range containers { fmt.Print("Stopping container ", c.ID[:10], "... ") if err := cli.ContainerStop(ctx, c.ID, nil); err != nil { panic(err) } fmt.Println("Success") } }
Вывод логов отдельно взятого контейнера
Вы можете работать с отдельно взятыми контейнерами. В следующем примере выводятся логи контейнера с указанным идентификатором. Перед запуском вам нужно изменить идентификатор контейнера, чьи логи вы хотите получить.
package main import ( "context" "io" "os" "github.com/docker/docker/api/types" "github.com/docker/docker/client" ) func main() { ctx := context.Background() cli, err := client.NewEnvClient() if err != nil { panic(err) } options := types.ContainerLogsOptions{ShowStdout: true} // Измените id контейнера здесь out, err := cli.ContainerLogs(ctx, "f1064a8a4c82", options) if err != nil { panic(err) } io.Copy(os.Stdout, out) }
Получение списка images
Этот пример эквивалентен запуску команды docker image ls
package main import ( "context" "fmt" "github.com/docker/docker/api/types" "github.com/docker/docker/client" ) func main() { cli, err := client.NewEnvClient() if err != nil { panic(err) } // Получение списка образов images, err := cli.ImageList(context.Background(), types.ImageListOptions{}) if err != nil { panic(err) } for _, image := range images { fmt.Println(image.ID) } }
Pull
Этот пример эквивалентен запуску команды docker pull
package main import ( "context" "io" "os" "github.com/docker/docker/api/types" "github.com/docker/docker/client" ) func main() { ctx := context.Background() cli, err := client.NewEnvClient() if err != nil { panic(err) } // docker pull alpine out, err := cli.ImagePull(ctx, "docker.io/library/alpine", types.ImagePullOptions{}) if err != nil { panic(err) } defer out.Close() io.Copy(os.Stdout, out) }
Скачивание образа с аутентификацией пользователя
Этот пример эквивалентен запуску команды docker pull, с аутентификацией.
Данные аутентификации отправляются в открытом виде. Официальные docker registry используют HTTPS,
частные registry так же должны быть настроены на передачу данных с использованием HTTPS.
package main import ( "context" "encoding/base64" "encoding/json" "io" "os" "github.com/docker/docker/api/types" "github.com/docker/docker/client" ) func main() { ctx := context.Background() cli, err := client.NewEnvClient() if err != nil { panic(err) } // Создание конфига с данными для аутентификации authConfig := types.AuthConfig{ Username: "username", Password: "password", } encodedJSON, err := json.Marshal(authConfig) if err != nil { panic(err) } authStr := base64.URLEncoding.EncodeToString(encodedJSON) out, err := cli.ImagePull(ctx, "docker.io/library/alpine", types.ImagePullOptions{RegistryAuth: authStr}) if err != nil { panic(err) } defer out.Close() io.Copy(os.Stdout, out) }
