package docker import ( "context" "io" "os" "github.com/docker/docker/api/types" "github.com/docker/docker/api/types/container" "github.com/docker/docker/client" ) // CreateDockerClient 创建Docker客户端 func CreateDockerClient(ctx context.Context) (*client.Client, error) { cli, err := client.NewClientWithOpts(client.FromEnv, client.WithAPIVersionNegotiation()) if err != nil { return nil, err } return cli, nil } // GetDockerSocketPath 获取Docker Socket路径 func GetDockerSocketPath() (string, error) { // 检查常见的Docker socket路径 socketPaths := []string{ "/var/run/docker.sock", "/run/podman/podman.sock", "$HOME/.colima/docker.sock", "$XDG_RUNTIME_DIR/docker.sock", "$XDG_RUNTIME_DIR/podman/podman.sock", `\\.\pipe\docker_engine`, "$HOME/.docker/run/docker.sock", } for _, path := range socketPaths { if _, err := os.Stat(path); err == nil { return path, nil } } // 如果找不到,返回默认路径 return "/var/run/docker.sock", nil } // PullImage 拉取Docker镜像 func PullImage(cli *client.Client, dockerHost, imageName string) error { ctx := context.Background() reader, err := cli.ImagePull(ctx, imageName, types.ImagePullOptions{}) if err != nil { return err } defer reader.Close() // 读取并丢弃输出,确保拉取完成 _, err = io.Copy(io.Discard, reader) return err } // CreateAndStartContainer 创建并启动容器 func CreateAndStartContainer(cli *client.Client, imageName string, cmd []string, env []string, binds []string, ports map[string]string, containerName string) error { ctx := context.Background() // 配置容器 config := &container.Config{ Image: imageName, Env: env, } if cmd != nil { config.Cmd = cmd } hostConfig := &container.HostConfig{ Binds: binds, } // 如果有端口映射配置 if ports != nil && len(ports) > 0 { // 这里可以根据需要添加端口映射逻辑 // hostConfig.PortBindings = portBindings } // 创建容器 resp, err := cli.ContainerCreate(ctx, config, hostConfig, nil, nil, containerName) if err != nil { return err } // 启动容器 return cli.ContainerStart(ctx, resp.ID, types.ContainerStartOptions{}) } // DeleteContainer 停止并删除指定名称的容器 func DeleteContainer(cli *client.Client, containerName string) error { ctx := context.Background() // 首先尝试停止容器 timeout := 10 err := cli.ContainerStop(ctx, containerName, container.StopOptions{ Timeout: &timeout, }) if err != nil { // 如果容器已经停止或不存在,继续执行删除操作 // 这里不返回错误,因为我们的目标是删除容器 } // 删除容器 err = cli.ContainerRemove(ctx, containerName, types.ContainerRemoveOptions{ Force: true, // 强制删除,即使容器正在运行 }) if err != nil { return err } return nil }