αž€αžΆαžšαž‚αŸ’αžšαž”αŸ‹αž‚αŸ’αžšαž„αž’αž»αž„ Docker αž“αŸ…αž€αŸ’αž“αž»αž„ Go

αž―αž€αžŸαžΆαžš!

αž“αŸ…αž–αŸαž›αž’αŸ’αž“αž€αžŸαž˜αŸ’αžšαŸαž…αž…αž·αžαŸ’αžαžŸαžšαžŸαŸαžšαž€αž„αŸ‹αž•αŸ’αž‘αžΆαž›αŸ‹αžαŸ’αž›αž½αž“αžšαž”αžŸαŸ‹αž’αŸ’αž“αž€αžŸαž˜αŸ’αžšαžΆαž”αŸ‹αž€αžΆαžšαž…αžΆαž”αŸ‹αž‘αŸ†αž–αž€αŸ‹αž–αžΈαž˜αž‡αŸ’αžˆαž˜αžŽαŸ’αžŒαž› docker αž¬αž–αžΈαž”αž‰αŸ’αž‡αžΈαžˆαŸ’αž˜αŸ„αŸ‡αžŠαžΎαž˜αŸ’αž”αžΈαž’αŸ’αžœαžΎαž”αž…αŸ’αž…αž»αž”αŸ’αž”αž“αŸ’αž“αž—αžΆαž–/αžŠαŸ†αžŽαžΎαžšαž€αžΆαžšαž€αž»αž„αžαžΊαž“αŸαžšαžŠαŸ„αž™αžŸαŸ’αžœαŸαž™αž”αŸ’αžšαžœαžαŸ’αžαž·αž“αŸ…αž›αžΎαž˜αŸ‰αžΆαžŸαŸŠαžΈαž“αž˜αŸ αž’αŸ’αž“αž€αž’αžΆαž…αžšαž€αžƒαžΎαž‰ Docker Cli αž˜αžΆαž“αž”αŸ’αžšαž™αŸ„αž‡αž“αŸ αžŠαŸ‚αž›αž“αžΉαž„αž‡αž½αž™αž‚αŸ’αžšαž”αŸ‹αž‚αŸ’αžšαž„ Docker daemon αž“αŸ…αž›αžΎαž”αŸ’αžšαž–αŸαž“αŸ’αž’αžšαž”αžŸαŸ‹αž’αŸ’αž“αž€αŸ”
αž€αžΆαžšαž‚αŸ’αžšαž”αŸ‹αž‚αŸ’αžšαž„αž’αž»αž„ Docker αž“αŸ…αž€αŸ’αž“αž»αž„ Go

αžŠαžΎαž˜αŸ’αž”αžΈαžŠαŸ†αžŽαžΎαžšαž€αžΆαžšαž’αŸ’αž“αž€αž“αžΉαž„αžαŸ’αžšαžΌαžœαž€αžΆαžšαž€αŸ†αžŽαŸ‚ 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)
}

αž‘αž‘αž½αž›αž”αžΆαž“αž”αž‰αŸ’αž‡αžΈαžšαžΌαž”αž—αžΆαž–

αž§αž‘αžΆαž αžšαžŽαŸαž“αŸαŸ‡αž‚αžΊαžŸαŸ’αž˜αžΎαž“αžΉαž„αž€αžΆαžšαžŠαŸ†αžŽαžΎαžšαž€αžΆαžšαž–αžΆαž€αŸ’αž™αž”αž‰αŸ’αž‡αžΆ 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)
    }
}

αž‘αžΆαž‰

αž§αž‘αžΆαž αžšαžŽαŸαž“αŸαŸ‡αž‚αžΊαžŸαŸ’αž˜αžΎαž“αžΉαž„αž€αžΆαžšαžŠαŸ†αžŽαžΎαžšαž€αžΆαžšαž–αžΆαž€αŸ’αž™αž”αž‰αŸ’αž‡αžΆ 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 αž•αŸ’αž›αžΌαžœαž€αžΆαžšαž”αŸ’αžšαžΎ HTTPS,
αž€αžΆαžšαž…αž»αŸ‡αžˆαŸ’αž˜αŸ„αŸ‡αž―αž€αž‡αž“αž€αŸαžαŸ’αžšαžΌαžœαžαŸ‚αž€αŸ†αžŽαžαŸ‹αžšαž…αž“αžΆαžŸαž˜αŸ’αž–αŸαž“αŸ’αž’αžŠαžΎαž˜αŸ’αž”αžΈαž•αŸ’αž‘αŸαžšαž‘αž·αž“αŸ’αž“αž“αŸαž™αžŠαŸ„αž™αž”αŸ’αžšαžΎ 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)
}

αž”αŸ’αžšαž—αž–: www.habr.com

αž”αž“αŸ’αžαŸ‚αž˜αž˜αžαž·αž™αŸ„αž”αž›αŸ‹