使用Docker Python API开启auto_remove=True时如何获取stdout?
问题:开启
auto_remove=True时无法获取容器stdout 我需要用auto_remove=True替代remove=True实现更可靠的容器删除,但以下代码无法获取stdout:
import docker client = docker.from_env() container_options = { 'image': 'age', 'command': ["sh", "/predictAge.sh", "2"], 'auto_remove': True, 'detach': True, 'stderr':True, 'stdout':True } container = client.containers.run(**container_options) stdout_bytes = container.logs(stdout=True, stderr=False) stdout_str = stdout_bytes.decode('utf-8') print(stdout_str)
运行后报错,容器在获取stdout前就被移除:
raise cls(e, response=response, explanation=explanation) from e docker.errors.NotFound: 404 Client Error for http+docker://localhost/v1.43/containers/1da46e6a02d621ed01ed38063aea75cf43b2806246430bdffd312567fea90738/json: Not Found ("No such container: 1da46e6a02d621ed01ed38063aea75cf43b2806246430bdffd312567fea90738")
用通用测试代码(基于hello-world镜像)仍会触发相同错误:
import docker client = docker.from_env() container_options = { 'image': 'hello-world', 'auto_remove': True, 'stdout':True } container = client.containers.run(**container_options) stdout_bytes = container.logs(stdout=True, stderr=False) stdout_str = stdout_bytes.decode('utf-8') print(stdout_str)
解决方案
核心原因是:auto_remove=True会让容器在退出后立刻销毁。如果是后台运行(detach=True),容器可能在调用logs()前就被删;非后台模式下,run()阻塞到容器结束后,容器已被移除,返回的不是容器对象而是输出内容,此时调用logs()必然报错。
针对两种场景分别处理:
场景1:非后台运行(无需detach=True)
直接使用containers.run()的返回值,开启stdout=True且不设置detach=True时,run()会直接返回容器的stdout字节数据,无需调用logs():
import docker client = docker.from_env() container_options = { 'image': 'hello-world', 'auto_remove': True, 'stdout': True, 'stderr': False # 按需控制是否捕获stderr } # run()直接返回stdout的字节数据 stdout_bytes = client.containers.run(**container_options) stdout_str = stdout_bytes.decode('utf-8') print(stdout_str)
场景2:后台运行(需要detach=True)
这种情况要确保在容器被销毁前捕获日志,最可靠的方式是用流式日志实时获取输出:
import docker client = docker.from_env() container_options = { 'image': 'age', 'command': ["sh", "/predictAge.sh", "2"], 'auto_remove': True, 'detach': True, 'stdout': True, 'stderr': True } container = client.containers.run(**container_options) # 流式获取日志,直到容器结束 logs = [] for log in container.logs(stream=True, stdout=True, stderr=False): logs.append(log) # 合并日志并解码 stdout_str = b''.join(logs).decode('utf-8') print(stdout_str)
也可以先调用wait()等待容器退出,再尝试获取日志(这种方式依赖容器退出到销毁的时间窗口,可靠性略低于流式日志):
container.wait() stdout_bytes = container.logs(stdout=True, stderr=False) print(stdout_bytes.decode('utf-8'))
内容的提问来源于stack exchange,提问作者doom4
相关产品推荐
相关产品推荐

