使用Docker Go SDK执行脚本后,如何获取自动删除容器的日志?
背景
我在容器内运行以下命令:
docker run -it --rm \ --mount type=volume,src=synapse-data,dst=/data \ -e SYNAPSE_SERVER_NAME=my.matrix.host \ -e SYNAPSE_REPORT_STATS=yes \ matrixdotorg/synapse:latest generate
基于Synapse v1.56.0的Docker配置
Docker SDK 使用
我使用了Client.ContainerCreate抽象方法,核心需求是启用:
AutoRemove: true,
目的是实现容器使用后自动删除,比如设置意外退出时也能自动清理。我还将容器命名为server_setup_temporary_container,提示用户这是临时设置容器。若设置未正常关闭容器,用户可手动清理以释放绑定卷。
generate脚本遇到的问题
我无法通过容器日志API获取日志,因为容器执行完generate后就会退出,日志随容器被删除。
相比之下,PostgreSQL容器作为守护进程运行,需要显式关闭,这种日志获取方式能正常工作,但执行一次性脚本的容器却不行!
我目前有几个思路:
- 在
generate后执行sleep 3600,再显式关闭容器 - 尝试直接从
ContainerStart或ContainerCreate获取日志,但研究API后发现可能未实现此功能
我不想放弃AutoRemove: true的配置。
源代码
使用StartContainer抽象方法
// Start and run container containerId, err := s.dockerClient.myStartContainer(docker.ContainerStartConfig{ Image: matrixImage, Volumes: []docker.ContainerVolume{ docker.ContainerVolume{ Source: volume, Target: "/data", }, }, Env: []string{ fmt.Sprintf("SYNAPSE_SERVER_NAME=%s", domain), "SYNAPSE_REPORT_STATS=no", }, Cmds: []string{ "generate", }, })
StartContainer抽象方法实现
func (c *Client) myStartContainer(cfg ContainerStartConfig) (string, error) { if c.client == nil { return "", errors.New(noClientErr) } if len(cfg.Image) == 0 { return "", errors.New(noImageErr) } containerConfig := container.Config{ Image: cfg.Image, } hostConfig := container.HostConfig{ AutoRemove: true, } if cfg.Env != nil { containerConfig.Env = cfg.Env } if cfg.Cmds != nil { containerConfig.Cmd = make(strslice.StrSlice, len(cfg.Cmds)) for i, _cmd := range cfg.Cmds { containerConfig.Cmd[i] = _cmd } } if cfg.Volumes != nil { hostConfig.Mounts = make([]mount.Mount, len(cfg.Volumes)) for i, v := range cfg.Volumes { hostConfig.Mounts[i] = mount.Mount{ Type: "volume", Source: v.Source, Target: v.Target, } } } var networkingConfig *network.NetworkingConfig if cfg.Networks != nil { networkingConfig = &network.NetworkingConfig{EndpointsConfig: map[string]*network.EndpointSettings{}} for _, nw := range cfg.Networks { n := nw.Name networkingConfig.EndpointsConfig[n] = &network.EndpointSettings{Aliases: nw.Aliases} } } cont, err := c.client.ContainerCreate( c.ctx, &containerConfig, &hostConfig, networkingConfig, nil, "server_setup_temporary_container", ) if err != nil { return "", err } colorlogger.Log.Info("Container ID of "+colorlogger.LYellow, cfg.Image, colorlogger.CLR+" is "+cont.ID) if err := c.client.ContainerStart(c.ctx, cont.ID, types.ContainerStartOptions{}); err != nil { return "", err } return cont.ID, nil }
整体场景
我执行此设置是为了配置后续用docker compose运行的容器,因为部分设置需要对容器进行显式修改,无法通过声明式方式完成。
内容的提问来源于stack exchange,提问作者qknight
相关产品推荐
相关产品推荐

