安装软件包

go get github.com/docker/docker/client

操控镜像

获取镜像列表

func GetImageList() (images []image.Summary, err error) {
	cli, err := client.NewClientWithOpts(client.FromEnv, client.WithAPIVersionNegotiation())
	if err != nil {
		return nil, err
	}
	defer cli.Close()
	
	ctx := context.Background()
	images, err = cli.ImageList(ctx, image.ListOptions{})
	if err != nil {
		return nil, err
	}
	
	return images, err
}

获取镜像

func GetImage(imageID string) (imageInspect types.ImageInspect, err error) {
	cli, err := client.NewClientWithOpts(client.FromEnv, client.WithAPIVersionNegotiation())
	if err != nil {
		return imageInspect, err
	}
	defer cli.Close()
 
	ctx := context.Background()
	imageInspect, _, err = cli.ImageInspectWithRaw(ctx, imageID)
	if err != nil {
		return imageInspect, err
	}
 
	return imageInspect, err
}

拉取镜像

func PullImage(refStr string) (err error) {
	cli, err := client.NewClientWithOpts(client.FromEnv, client.WithAPIVersionNegotiation())
	if err != nil {
		return err
	}
	defer cli.Close()
	
	ctx := context.Background()
	out, err := cli.ImagePull(ctx, refStr, image.PullOptions{})
	if err != nil {
		return err
	}
	io.Copy(ioutil.Discard, out)
	defer out.Close()
	
	return err
}

带认证拉取镜像

func PullImageWithAuth(refStr string, username string, password string) (err error) {
	cli, err := client.NewClientWithOpts(client.FromEnv, client.WithAPIVersionNegotiation())
	if err != nil {
		return err
	}
	defer cli.Close()
	
	ctx := context.Background()
	authConfig := registry.AuthConfig{
		Username: username,
		Password: password,
	}
	encodedJSON, err := json.Marshal(authConfig)
	if err != nil {
		return err
	}
	authStr := base64.URLEncoding.EncodeToString(encodedJSON)
	out, err := cli.ImagePull(ctx, refStr, image.PullOptions{RegistryAuth: authStr})
	if err != nil {
		return err
	}
	io.Copy(ioutil.Discard, out)
	defer out.Close()
	
	return err
}

删除镜像

func RemoveImage(imageID string) (err error) {
	cli, err := client.NewClientWithOpts(client.FromEnv, client.WithAPIVersionNegotiation())
	if err != nil {
		return err
	}
	defer cli.Close()
	
	ctx := context.Background()
	_, err = cli.ImageRemove(ctx, imageID, image.RemoveOptions{Force: true, PruneChildren: true})
	if err != nil {
		return err
	}
	return err
}

操控容器

获取容器列表

func GetContainerList() (containers []types.Container, err error) {
	cli, err := client.NewClientWithOpts(client.FromEnv, client.WithAPIVersionNegotiation())
	if err != nil {
		return containers, err
	}
	defer cli.Close()
	
	ctx := context.Background()
	containers, err = cli.ContainerList(ctx, container.ListOptions{All: true})
	if err != nil {
		return containers, err
	}
	
	return containers, err
}

获取容器

func GetContainer(containerID string) (containerJSON types.ContainerJSON, err error) {
	cli, err := client.NewClientWithOpts(client.FromEnv, client.WithAPIVersionNegotiation())
	if err != nil {
		return containerJSON, err
	}
	defer cli.Close()
	
	ctx := context.Background()
	containerJSON, err = cli.ContainerInspect(ctx, containerID)
	if err != nil {
		return containerJSON, err
	}
	
	return containerJSON, err
}

创建容器

func CreateContainer(imageID string) (containerID string, err error) {
	cli, err := client.NewClientWithOpts(client.FromEnv, client.WithAPIVersionNegotiation())
	if err != nil {
		return containerID, err
	}
	defer cli.Close()
	
	image, err := GetImage(imageID)
	if err != nil {
		return containerID, err
	}
	
	exposedPorts := image.Config.ExposedPorts
	randomPorts, err := freeport.GetFreePorts(len(exposedPorts))
	if err != nil {
		return containerID, err
	}
 
	portBindings := nat.PortMap{}
	i := 0
	for port := range exposedPorts {
		portBindings[port] = []nat.PortBinding{
			{
				HostIP:   "0.0.0.0",
				HostPort: fmt.Sprintf("%d", randomPorts[i]),
			},
		}
		i++
	}
	
	ctx := context.Background()
	res, err := cli.ContainerCreate(ctx, &container.Config{
		Image:        imageID,
		ExposedPorts: exposedPorts,
	}, &container.HostConfig{
		PortBindings: portBindings,
	}, nil, nil, "")
	if err != nil {
		return containerID, err
	}
 
	return res.ID, err
}

启动容器

func StartContainer(containerID string) (err error) {
	cli, err := client.NewClientWithOpts(client.FromEnv, client.WithAPIVersionNegotiation())
	if err != nil {
		return err
	}
	defer cli.Close()
 
	ctx := context.Background()
	err = cli.ContainerStart(ctx, containerID, container.StartOptions{})
	if err != nil {
		return err
	}
 
	return err
}

停止容器

func StopContainer(containerID string) (err error) {
	cli, err := client.NewClientWithOpts(client.FromEnv, client.WithAPIVersionNegotiation())
	if err != nil {
		return err
	}
	defer cli.Close()
 
	ctx := context.Background()
	timeout := 10
	stopOptions := container.StopOptions{Timeout: &timeout}
	err = cli.ContainerStop(ctx, containerID, stopOptions)
	if err != nil {
		return err
	}
 
	return err
}

删除容器

func RemoveContainer(containerID string) (err error) {
	cli, err := client.NewClientWithOpts(client.FromEnv, client.WithAPIVersionNegotiation())
	if err != nil {
		return err
	}
	defer cli.Close()
	
	ctx := context.Background()
	removeOptions := container.RemoveOptions{
		RemoveVolumes: true,
		RemoveLinks:   false,
		Force:         true,
	}
	err = cli.ContainerRemove(ctx, containerID, removeOptions)
	if err != nil {
		return err
	}
 
	return err
}