containers.run() returns None for the local logging driver, now the Docker Desktop 4.94 default
評価
- 難易度
- 3/5
- 見積もり時間
- 1〜2日
- 初心者へのやさしさ
- 76/100
調査の方向性
Start with docker/models/containers.py and trace how containers.run() reads logs based on the logging driver; check when an unreadable driver raises an error on the streaming path. Then review the docstring and the existing test_run_with_json_file_driver and none integration cases in tests/integration/models_containers_test.py; done means readable local logs are returned, the none case remains handled, and the documented behavior matches.
索引モデルが issue の本文から書いたものです。
説明
containers.run() returns None instead of the container's output when the container uses the local logging driver. Docker Desktop 4.94.0 made local the default for new Linux containers, so plain run() calls that previously returned output now silently return None for Docker Desktop users.
Environment
- Docker Desktop 4.94.0 on macOS (arm64), Docker Engine 29.8.2, API version 1.56
- docker-py 7.1.0 and 7.2.0 (both behave the same), Python 3.11
docker info --format '{{.LoggingDriver}}'printslocal, with nolog-driverset indaemon.json
The Docker Desktop 4.94.0 release notes say: "Changed the default logging driver for new Linux containers to local to enable automatic log rotation and reduce disk usage".
Reproduction
import docker
client = docker.from_env()
out = client.containers.run("alpine:latest", "echo hello", remove=True)
print(repr(out))
Expected: b'hello\n'
Actual: None
Passing log_config=docker.types.LogConfig(type="json-file") makes the same call return b'hello\n'.
Cause
DockerClient.containers.run() decides whether to read the container's output by comparing the configured driver name against a fixed list (docker/models/containers.py on main):
logging_driver = container.attrs['HostConfig']['LogConfig']['Type']
out = None
if logging_driver == 'json-file' or logging_driver == 'journald':
out = container.logs(stdout=stdout, stderr=stderr, stream=True, follow=True)
...
if stream or out is None:
return out
return b''.join(out)
For any other driver out stays None and run() returns None without an error. The list was added in 2017 (commit 62fda980e4, "client.containers.run returns None if none of json-file or journald logging drivers used", fixing #1688). At the time the Engine API documentation said logs could only be read with those two drivers, and run() on e.g. syslog failed with 500 ... configured logging driver does not support reading.
That premise no longer holds:
- The
localdriver is readable. On the same daemon, running detached and then reading the logs works and returns the output:k = client.containers.run("alpine:latest", "echo hello", detach=True); k.wait(); k.logs()returnsb'hello\n'withHostConfig.LogConfig.Type == 'local'.docker logsalso works. - The
localdriver has been available since at least Engine 18.09 (it is listed in thedocker infooutput in #2866). - The Engine's dual logging documentation says
docker logscan read container logs "regardless of the configured logging driver or plugin", unlesscache-disabledis set.
There is still a genuinely unreadable case. With the none driver, container.logs() raises APIError 501, which is what the 2017 change was protecting against.
Impact
Anything that relies on the return value of run() breaks on Docker Desktop 4.94 and later without any change on the caller's side. One example is the DataHub CLI (acryl-datahub, datahub docker quickstart), whose preflight check runs a throwaway alpine container to measure free disk space and calls .decode() on the result, so it now fails immediately with AttributeError: 'NoneType' object has no attribute 'decode'.
Possible fixes
- Add
'local'to the list. One line, and fixes the current case, but other readable drivers (including remote drivers that dual logging makes readable) would still silently returnNone. - Stop deciding by driver name. Always try to read, and return
Noneonly if the Engine answers that the driver does not support reading (the 501 above). This matches current Engine behaviour and cannot go stale when drivers are added. It needs a check of when the error is raised on the streaming path (stream=True, follow=True).
Whichever is chosen, the run() docstring currently documents the old behaviour ("STDOUT and STDERR may be read only if either json-file or journald logging driver used... a None object is returned instead", linking to the v1.30 API docs) and would need updating. The Swarm service logs docstrings (docker/models/services.py, docker/api/service.py) carry a similar note but cover a different endpoint, so I have not assumed they are affected.
For tests, tests/integration/models_containers_test.py already has test_run_with_json_file_driver and a none case that asserts out is None, so a local case beside them would follow the existing pattern. The unit tests only exercise the readable path, because fake_api.py hard-codes "LogConfig": {"Type": "json-file"} in the inspect response, so a parametrized unit test over the driver type would also cover the branch that currently has no unit coverage.
Related
Not duplicates, but adjacent reports of run() and logging-driver behaviour: #2866 (run() hangs with the journald driver), #2367, #1924.
Happy to send a PR for either option.
- 主要言語
- Python
- スター
- 7.2k
- フォーク
- 1.7k
- PR マージ指標
- 30日以内にマージされた PR はありません
環境構築
- Dockerfile または Docker Compose ファイルあり
- プルリクエストのテンプレートなし
- コントリビューションガイドを読む
はじめの一歩
- issue を最後まで読み、次にプロジェクトのコントリビューションガイドを読みます。
- 着手することを issue にコメントします — 二人が同じ作業をするのを防げます。
- リポジトリをフォークし、ブランチを切って変更します。
- issue 番号を参照したプルリクエストを送ります。
docker/docker-py のほかの issue
-
.dockerignore matching ignores filename case on Linux対応中かも @locker95 が 8 日前に担当しました。 オープン
難易度 2/5 1〜3時間 初心者へのやさしさ 82/100
-
Add `pull` to the list of kwargs to pass to create and run対応中かも @zainnadeem786 が 138 日前に担当しました。 オープン
難易度 2/5 1〜3時間 初心者へのやさしさ 75/100
-
難易度 1/5 1時間未満 初心者へのやさしさ 68/100
-
難易度 2/5 1〜3時間 初心者へのやさしさ 65/100
-
.dockerignore reinclusion retains unrelated files in a glob-excluded directory対応中かも @SparkDrago05 が 6 日前に担当しました。 オープン
難易度 3/5 1〜2日 初心者へのやさしさ 74/100
docker/docker-py の issue をすべて見る
似ている issue
-
bug
難易度 2/5 1〜3時間 初心者へのやさしさ 68/100
jbacalso24/mimry#291 ·
メンテナーはふだん 1 日以内に返信
-
good first issue
難易度 2/5 1時間未満 初心者へのやさしさ 82/100
eli-alvarado/us-watchlist-alerts#14 ·
メンテナーはふだん 1 日以内に返信
-
from-review-extraction python severity:nit
難易度 2/5 1〜3時間 初心者へのやさしさ 80/100
LearningCircuit/local-deep-research#7462 ·
メンテナーはふだん 2 日以内に返信
-
難易度 2/5 1〜3時間 初心者へのやさしさ 82/100
cathrynlavery/diagram-design#441 ·
メンテナーはふだん 2 日以内に返信
-
[Cleanup] Include the public header in work_split.cpp対応中かも @blozano-tt が今日担当しました。 オープン
難易度 2/5 1〜3時間 初心者へのやさしさ 82/100
tenstorrent/tt-metal#60850 ·
メンテナーはふだん 1 日以内に返信