Golang使用docker sdk管理docker

包括列出容器、创建容器、删除容器、进入容器、构建镜像等操作。

Go 复制代码
package dockertool

import (
	"context"
	"fmt"
	"github.com/docker/docker/api/types"
	"github.com/docker/docker/api/types/container"
	"github.com/docker/docker/api/types/image"
	"github.com/docker/docker/client"
	"io"
	"os"
)

// 列出所有容器
func ListContainers() ([]types.Container, error) {
	apiClient, err := client.NewClientWithOpts(client.FromEnv, client.WithAPIVersionNegotiation())
	if err != nil {
		return nil, err
	}
	defer apiClient.Close()

	containers, err := apiClient.ContainerList(context.Background(), container.ListOptions{All: true})
	if err != nil {
		return nil, err
	}

	// TODO : for debug
	for _, ctr := range containers {
		fmt.Printf("%s %s %q (status: %s)\n", ctr.ID, ctr.Image, ctr.Names, ctr.Status)
	}

	return containers, nil
}

// 删除所有镜像和容器
func DeleteAllContainersAndImages() error {
	apiClient, err := client.NewClientWithOpts(client.FromEnv, client.WithAPIVersionNegotiation())
	if err != nil {
		return err
	}
	defer apiClient.Close()

	//停止、删除所有容器
	containers, err := apiClient.ContainerList(context.Background(), container.ListOptions{All: true})
	if err != nil {
		return err
	}
	for _, ctr := range containers {
		err = apiClient.ContainerStop(context.Background(), ctr.ID, container.StopOptions{})
		if err != nil {
			return err
		}
		err = apiClient.ContainerRemove(context.Background(), ctr.ID, container.RemoveOptions{})
		if err != nil {
			return err
		}
	}
	fmt.Println("All containers deleted")
	//删除所有镜像
	images, err := apiClient.ImageList(context.Background(), image.ListOptions{})
	if err != nil {
		return err
	}
	for _, im := range images {
		_, err := apiClient.ImageRemove(context.Background(), im.ID, image.RemoveOptions{})
		if err != nil {
			return err
		}
	}
	fmt.Println("All images deleted")
	return nil
}

// 创建容器并运行
func BuildContainer(ContainerName string, ImageName string) error {
	cli, err := client.NewClientWithOpts(client.FromEnv, client.WithAPIVersionNegotiation())
	if err != nil {
		return err
	}
	defer cli.Close()
	config := &container.Config{
		Image: ImageName,
	}

	// 创建容器
	resp, err := cli.ContainerCreate(context.Background(), config, nil, nil, nil, ContainerName)
	if err != nil {
		panic(err)
	}

	fmt.Printf("Container created with ID: %s\n", resp.ID)

	// 启动容器
	if err := cli.ContainerStart(context.Background(), resp.ID, container.StartOptions{}); err != nil {
		panic(err)
	}

	fmt.Println("Container started")
	return nil
}

// 本地创建镜像
func BuildImage(ImageName string, TarPath string, DockerfilePath string) error {
	cli, err := client.NewClientWithOpts(client.FromEnv, client.WithAPIVersionNegotiation())
	if err != nil {
		return err
	}
	defer cli.Close()
	// 设置构建上下文(这里使用文件路径作为示例)
	// 注意:这个路径应该包含 Dockerfile 和所有需要的构建文件
	buildContext, err := os.Open(TarPath)
	if err != nil {
		return err
	}
	defer buildContext.Close()
	// 设置构建选项
	options := types.ImageBuildOptions{
		Tags:           []string{ImageName},
		Dockerfile:     DockerfilePath,
		SuppressOutput: false, // 设置为 false 以获取构建日志
		NoCache:        false, // 不使用缓存
		Remove:         true,  // 构建完成后删除中间容器
		ForceRemove:    true,  // 强制删除中间容器
		PullParent:     true,  // 如果基础镜像不存在,则尝试拉取
	}
	// 触发构建
	response, err := cli.ImageBuild(context.Background(), buildContext, options)
	if err != nil {
		return err
	}
	fmt.Println("Built image " + ImageName)
	defer response.Body.Close()
	return nil
}

// 进入容器并执行命令
func ContainerProcess(ContainerID string, ProcessID string) error {
	cli, err := client.NewClientWithOpts(client.FromEnv, client.WithAPIVersionNegotiation())
	if err != nil {
		return err
	}
	defer cli.Close()
	execConfig := types.ExecConfig{
		Cmd:          []string{"ps -f -p" + ProcessID}, // 使用bash执行ps命令,取决于容器内环境
		AttachStdin:  false,
		AttachStdout: true,
		AttachStderr: true,
		Tty:          false,
	}
	// 创建一个exec实例
	resp, err := cli.ContainerExecCreate(context.Background(), ContainerID, execConfig)
	if err != nil {
		return err
	}
	// 连接到exec实例的输出
	readCloser, err := cli.ContainerExecAttach(context.Background(), resp.ID, types.ExecStartCheck{})
	if err != nil {
		return err
	}
	defer readCloser.Close()
	_, err = io.Copy(os.Stdout, readCloser.Reader)
	if err != nil {
		return err
	}
	return nil
}

在linux环境中运行:

如果你在windows环境编程,docker在linux且是amd64架构,在代码目录里打开终端,输入

$env:GOOS="linux"

$env:GOARCH="amd64"

go build -o output

这样生成编译后的结果output,再把它放到linux环境中,并设置文件权限chmod 777 output,最后执行./output。

相关推荐
长河1 天前
Java开发者LLM实战——LangChain4j最新版教学知识库实战
java·开发语言
Cyan_RA91 天前
SpringMVC @RequestMapping的使用演示和细节 详解
java·开发语言·后端·spring·mvc·ssm·springmvc
傻傻虎虎1 天前
【Docker】常用帮忙、镜像、容器、其他命令合集(2)
运维·docker·容器
是小崔啊1 天前
叩丁狼K8s - 概念篇
云原生·容器·kubernetes
再见晴天*_*1 天前
SpringBoot 中单独一个类中运行main方法报错:找不到或无法加载主类
java·开发语言·intellij idea
lqjun08271 天前
Qt程序单独运行报错问题
开发语言·qt
hdsoft_huge1 天前
Java & Spring Boot常见异常全解析:原因、危害、处理与防范
java·开发语言·spring boot
风中的微尘1 天前
39.网络流入门
开发语言·网络·c++·算法
未来之窗软件服务1 天前
幽冥大陆(二)RDIFSDK 接口文档:布草洗涤厂高效运营的技术桥梁C#—东方仙盟
开发语言·c#·rdif·仙盟创梦ide·东方仙盟
小冯记录编程1 天前
C++指针陷阱:高效背后的致命危险
开发语言·c++·visual studio