.dockerignore wildcard exceptions lose files inside excluded directories
还没有人认领这个 Issue。
评估
- 难度
- 3/5
- 预计耗时
- 1-2 天
- 新手友好度
- 80/100
- Issue 类型
- 缺陷
- 描述清晰度
- 描述清楚
- 活跃度
- 活跃
- 技术栈
- docker, python
- 领域
- build-system
调研方向
Start from docker.utils.tar (docker/utils/build.py) and follow how exclude patterns are converted into match rules for the context tarball; the bug is in how ** plus a ! exception is evaluated for nested paths. Run the issue's reproduce-wildcard.py script first to confirm it prints an empty SDK context file list, then look for the existing exclusion-pattern unit tests (tests/unit/utils_test.py) as the place to add a regression case. Done means all three a.txt files appear in the tar with ['**', '!**/a.txt'] while other exclusion cases keep behaving as before.
由索引模型根据 Issue 内容生成。
描述
🤖 this issue description was generated by an LLM. i reviewed it before submitting. 🤖
I used Codex for the investigation, reproduction scripts, and this draft.
When I generate a build context with docker.utils.tar, the rules ** and !**/a.txt omit every nested a.txt. Docker's BuildKit keeps those files with the same input. The SDK therefore drops files that the exception explicitly includes.
Reproduction
Save this script as reproduce-wildcard.py:
import tarfile
from pathlib import Path
from tempfile import TemporaryDirectory
import docker
from docker.utils import tar
patterns = ['**', '!**/a.txt']
files = ['foo/a.txt', 'foo/bar/a.txt', 'target/a.txt']
with TemporaryDirectory() as directory:
root = Path(directory)
(root / 'Dockerfile').write_text('FROM scratch\nCOPY . /\n')
(root / '.dockerignore').write_text('\n'.join(patterns) + '\n')
for relative in files:
path = root / relative
path.parent.mkdir(parents=True, exist_ok=True)
path.write_text(relative)
with tar(str(root), exclude=patterns.copy()) as context:
with tarfile.open(fileobj=context) as archive:
actual = sorted(name for name in archive.getnames() if name in files)
print('docker:', docker.__version__)
print('patterns:', patterns)
print('SDK context files:', actual)
I ran it in an isolated uv environment, using commit 56343ddf8f0c44281e151c2dad016c16cdb8393d:
uv run --isolated --no-project --no-config --no-cache \
--python /home/jyn/.local/share/mise/installs/python/3.14.7/bin/python3 \
--with 'docker @ git+https://github.com/docker/docker-py@56343ddf8f0c44281e151c2dad016c16cdb8393d' \
python reproduce-wildcard.py
The --python path selects my tested Python installation; use the path to your Python executable on another machine. The pinned requirement selects the upstream SDK rather than an installed copy. I did not modify the SDK or replace its modules with mocks. This reproducer creates disposable files and examines the SDK's context tar without contacting a Docker daemon.
Expected behavior
The SDK should retain foo/a.txt, foo/bar/a.txt, and target/a.txt. I built the same files with FROM scratch and COPY . / using BuildKit, and its local output retained all three.
Actual output
docker: 7.2.1.dev26+g56343ddf8
patterns: ['**', '!**/a.txt']
SDK context files: []
BuildKit control
I ran the following standalone control with Docker's active lima context and lima builder. It creates the same input files, runs docker buildx build with a local filesystem export, and enumerates every exported regular file before removing the temporary directories. The command uses the active Docker context and builder; another machine can use its own working configuration.
Buildx command and exported-file inspection
Save this script as buildkit-control-wildcard.py:
import subprocess
from pathlib import Path
from tempfile import TemporaryDirectory
patterns = ['**', '!**/a.txt']
files = ['foo/a.txt', 'foo/bar/a.txt', 'target/a.txt']
with TemporaryDirectory() as directory:
context = Path(directory) / 'input'
context.mkdir()
output = Path(directory) / 'output'
(context / 'Dockerfile').write_text('FROM scratch\nCOPY . /\n')
(context / '.dockerignore').write_text('\n'.join(patterns) + '\n')
for relative in files:
path = context / relative
path.parent.mkdir(parents=True, exist_ok=True)
path.write_text(relative)
subprocess.run([
'docker', 'buildx', 'build',
'--progress=plain', '--provenance=false',
'--output', f'type=local,dest={output}', str(context),
], check=True)
print('BuildKit output files:', sorted(
path.relative_to(output).as_posix()
for path in output.rglob('*') if path.is_file()
))
Run it with:
python3 buildkit-control-wildcard.py
I got this stdout; Buildx wrote its progress log to stderr and exited successfully:
BuildKit output files: ['foo/a.txt', 'foo/bar/a.txt', 'target/a.txt']
Related report
A commenter described a similar wildcard-exception failure in the closed issue #1514. I can reproduce the minimized case below using the current upstream commit.
https://github.com/docker/docker-py/issues/1514#issuecomment-298018267
Environment
- Docker SDK for Python:
7.2.1.dev26+g56343ddf8, using upstream commit56343ddf8f0c44281e151c2dad016c16cdb8393d. - Python:
3.14.7 (main, Sep 29 2026, 15:01:40) [Clang 22.1.3 ]. - OS/distribution: CachyOS Linux, rolling release (
BUILD_ID=rolling;/etc/os-releasedoes not defineVERSION_ID). - Kernel/platform:
Linux-7.2.9-1-cachyos-x86_64-with-glibc2.44. - Docker CLI:
29.8.2; Docker Engine:29.8.0(linux/amd64). - Buildx:
github.com/docker/buildx 0.37.2 2d379c0c3f22da0d2759d132a0ec81ca949098f0. - The SDK tar reproducer requires no engine connection; the separate BuildKit comparison used the versions above.
- 主要语言
- Python
- 星标
- 7.2k
- 派生
- 1.7k
- PR 合并指标
- 30 天内没有已合并 PR
环境准备
- 提供 Dockerfile 或 Docker Compose 文件
- 没有 Pull Request 模板
- 阅读贡献指南
从这里开始
- 先读完整个 Issue,再读项目的贡献指南。
- 在 Issue 下留言说明你要接手 —— 这能避免两个人做同样的事。
- Fork 仓库,在一个分支上完成修改。
- 提交 Pull Request,并在描述里引用这个 Issue 编号。
docker/docker-py 的其他 Issue
-
.dockerignore matching ignores filename case on Linux可能已有人在做 @locker95 于 12 天前认领。 未关闭
难度 2/5 1-3 小时 新手友好度 82/100
-
Add `pull` to the list of kwargs to pass to create and run可能已有人在做 @zainnadeem786 于 143 天前认领。 未关闭
难度 2/5 1-3 小时 新手友好度 75/100
-
难度 1/5 1 小时以内 新手友好度 68/100
-
难度 2/5 1-3 小时 新手友好度 65/100
-
containers.run() returns None for the local logging driver, now the Docker Desktop 4.94 default可能已有人在做 @locker95 于 7 天前认领。 未关闭
难度 3/5 1-2 天 新手友好度 76/100
相似的 Issue
-
idxmax/idxmin raise ValueError when a single partition is all-NA可能已有人在做 @Jason10191019999 今天认领。 未关闭needs triage
难度 2/5 1-3 小时 新手友好度 78/100
维护者通常 3 天内回复
-
bug
难度 2/5 1-3 小时 新手友好度 64/100
-
[BUG]: Windows GUI package of v1.17.0-rc3 has no GTK DLLs可能已有人在做 @andrut-ds 今天认领。 未关闭bug CI/CD Pactus-GUI Windows
难度 2/5 1-3 小时 新手友好度 82/100
pactus-project/pactus#2428 ·
维护者通常 1 天内回复
-
DiskDataset.reshard() can hang with a zero or negative shard size可能已有人在做 @Programmer-Develops 今天认领。 未关闭
难度 2/5 1-3 小时 新手友好度 78/100
维护者通常 19 天内回复
-
难度 2/5 1-3 小时 新手友好度 66/100
GNS3/gns3-server#3017 · 1 条评论 ·
维护者通常 1 天内回复