如何在 docker python API 中流式传输日志?

cat*_*eof 5 python docker

我正在使用 docker python API 从 Dockerfile 构建图像。

import os
import sys
import os.path
import docker


client = docker.from_env()
try:
    here = os.path.dirname(__file__)
    no_cache = False
    dockerfile = os.path.join(here, 'app', 'nextdir')
    image = client.images.build(path=dockerfile, tag='app:v.2.4', nocache=no_cache, stream=True)
Run Code Online (Sandbox Code Playgroud)

操作成功完成,但是我无法流式传输日志。API 说:

返回一个阻塞生成器,您可以迭代它以在发生时检索构建输出

当流=真。

如何在 python 中获取这些日志?

Eff*_*ePi 8

根据文档,图像构建现在返回一个包含图像和构建日志的元组

第一项是所构建图像的 Image 对象。第二项是构建日志作为 JSON 解码对象的生成器。

并相应地修改@havock解决方案:

import docker

client = docker.from_env()
image, build_logs = client.images.build(**your_build_kwargs)

for chunk in build_logs:
    if 'stream' in chunk:
        for line in chunk['stream'].splitlines():
            log.debug(line)
Run Code Online (Sandbox Code Playgroud)


Sha*_*tel 6

可以使用docker-py 中给出的低级 API 来流式传输 docker 构建日志,如下所示,

        here = os.path.dirname(__file__)
        dockerfile = os.path.join(here, 'app', 'nextdir')
        docker_client = docker.APIClient(base_url='unix://var/run/docker.sock')
        generator = docker_client.build(path=dockerfile, tag='app:v.2.4', rm=True)
        while True:
            try:
                output = generator.__next__
                output = output.strip('\r\n')
                json_output = json.loads(output)
                if 'stream' in json_output:
                    click.echo(json_output['stream'].strip('\n'))
            except StopIteration:
                click.echo("Docker image build complete.")
                break
            except ValueError:
                click.echo("Error parsing output from docker image build: %s" % output)
Run Code Online (Sandbox Code Playgroud)


Hav*_*vok 6

您可以使用低级API 客户端。该build()函数将返回一个生成器,您可以迭代该生成器以获取构建日志的块。

生成器将生成一个包含 JSON 对象的字符串,您可以调用json.loads()它,也可以使用decode=True函数中的参数build()来为您执行此操作。

一旦你'stream'从生成的字典中获取了密钥,你就可以将print()它发送到记录器,但如果你需要将其发送到记录器,最好逐行执行,因为接收到的块将包含不止一行。

此类代码的一种选择如下:

from docker import APIClient

client = APIClient(base_url='unix://var/run/docker.sock')

# Build docker image
log.info('Building docker image ...')
streamer = client.build(
    decode=True,
    path=args.path,
    tag=args.tag,
)

for chunk in streamer:
    if 'stream' in chunk:
        for line in chunk['stream'].splitlines():
            log.debug(line)
Run Code Online (Sandbox Code Playgroud)