You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.19 09:00:57