`up`: Compose `build:` service with no Features still builds a label-only stage; put the metadata on the container instead, as for `image:`
维护者通常 1 天内回复
还没有人认领这个 Issue。
评估
- 难度
- 3/5
- 预计耗时
- 1-2 天
- 新手友好度
- 45/100
- Issue 类型
- 重构
- 描述清晰度
- 基本清楚
- 活跃度
- 活跃
- 技术栈
- docker, docker-compose, typescript
- 领域
- build-system, cli
调研方向
The condition canAddLabelsToContainer && !imageBuildInfo.dockerfile in src/spec-node/containerFeatures.ts (around line 153) decides whether the label stage is generated. Check how buildAndExtendDockerCompose in src/spec-node/dockerCompose.ts writes the build override. Done when up on a Compose build: service with no Features puts the metadata label on the container and runs a plain docker compose build, and devcontainer build behaves as before.
由索引模型根据 Issue 内容生成。
描述
Identity: TBaltensperger @ nuitio/devcontainer
This comes from nuitio/devcontainer, a private repository that ships a dev-container template on the Compose build: route; the measurements below are from its CI runners.
What happens
With a Docker Compose config whose service uses build: (a Dockerfile) and a devcontainer.json that declares no Features, devcontainer up creating a new container does not run the service's Dockerfile as written. It writes a copy, Dockerfile-with-features, to a temp folder with one more stage that only adds the devcontainer.metadata label, and builds that copy with BUILDKIT_INLINE_CACHE=1.
For an image: service with no Features the CLI skips that stage and puts the metadata on the container as a label (#267). The build: route is left out of that only because of the !imageBuildInfo.dockerfile condition.
Code at v0.89.0 (the latest on npm; these files are unchanged on main at 155f8b2):
- No Features: labels go on the container only when there is no Dockerfile; otherwise the label stage is built.
containerFeatures.ts#L152-L160if (!featuresConfig) { if (canAddLabelsToContainer && !imageBuildInfo.dockerfile) { return { labels: { [imageMetadataLabel]: JSON.stringify(getDevcontainerMetadata(...).raw) } }; } return { featureBuildInfo: await getImageBuildOptions(params, config, dstFolder, baseName, imageBuildInfo) }; } - The label stage itself,
FROM $_DEV_CONTAINERS_BASE_IMAGE AS dev_containers_target_stageplusLABEL devcontainer.metadata=...:
containerFeatures.ts#L199-L217 - A
build:service always carriesimageBuildInfo.dockerfile:
dockerCompose.ts#L167-L184and
imageMetadata.ts,internalGetImageBuildInfoFromDockerfile - The Compose build override with
Dockerfile-with-featuresandBUILDKIT_INLINE_CACHE=1:
dockerCompose.ts#L197-L246(inline cache at L230-L234) docker compose buildruns whenever no container exists yet (noBuild = !!container), passingcanAddLabelsToContainer = true:
dockerCompose.ts#L394-L399and
dockerCompose.ts#L267-L297.
For animage:service with no Features the override has nobuild:section, so this build does nothing.- The labels-on-the-container path already exists for Compose: the labels go into the start override's
labels:
(dockerCompose.ts#L411-L412,
#L565-L567), and a laterupreads the metadata from the container's labels
(imageMetadata.ts#L441-L445).
Measurement
Dev Containers CLI 0.89.0, Docker 29.8.2, 12-CPU Linux runner. Each figure is the median of three devcontainer up runs that create a new container, timed from --log-level trace. No Features in either config, and every layer of the Dockerfile is cached.
| Compose service | up total |
build step |
|---|---|---|
image: |
12.7 s | 0.4 s (nothing to build) |
build: (Dockerfile) |
14.5 s | 3.3 s (range 2.6–4.0 s) |
Each new container on the Dockerfile route spends about 3 s more in the build step. Part of that is the cached rebuild of the service's own Dockerfile, which still has to run so that changes to it are picked up. The rest is the generated Dockerfile, the extra stage and the inline-cache export.
Why build: was left out, as far as I can tell
In #267, @chrmarti explained the split: LABEL allows larger values than --label (about 1.3 MB against 0.5 MB in testing), so --label is used "when adding metadata is the only reason for using an additional (or modified) Dockerfile". With a Dockerfile there is a build anyway, so the stage looked free. devcontainer build passes canAddLabelsToContainer = false and still bakes the label into the image, which is right.
Nothing in up needs the label on the image: a later up reads it from the container, and the image: route already depends on that. The metadata for a config with no Features is the same size on both routes, so the image: route already accepts the --label size limit.
The stage is not free either. Besides the time, building a generated copy of the Dockerfile from a temp folder causes trouble of its own:
- #969: a
Dockerfile.dockerignorenext to the original Dockerfile is ignored. - #1320: Buildx 0.37.2 bake refuses a Dockerfile that is outside the build context. That report is for
devcontainer buildwith animage:service; thisuppath generates the same kind of override.
Request
On up, for a Compose build: service with no Features, put the metadata on the container as a label, as for an image: service, and build the service as written with a plain docker compose build, with no generated Dockerfile, no extra stage and no extra build args.
The smallest change I can see: drop && !imageBuildInfo.dockerfile from the condition in containerFeatures.ts#L153. devcontainer build stays as it is, because it passes canAddLabelsToContainer = false. Then buildAndExtendDockerCompose writes no build override for the service, and the existing docker compose build builds the user's Dockerfile unchanged. The single-container Dockerfile route passes false explicitly in singleContainer.ts#L150 and could get the same treatment from up.
If the label size limit is the concern, one option is to keep the stage only when the serialized metadata is close to the --label limit.
- 主要语言
- TypeScript
- 星标
- 3k
- 派生
- 466
- 平均合并
- 13 小时 28 分钟
- 30 天内合并 PR
- 2
环境准备
在浏览器里用你自己的 GitHub 账号启动这个项目的开发容器。
- 没有 Dockerfile 或 Docker Compose 文件
- 没有 Pull Request 模板
- 阅读贡献指南
从这里开始
- 先读完整个 Issue,再读项目的贡献指南。
- 在 Issue 下留言说明你要接手 —— 这能避免两个人做同样的事。
- Fork 仓库,在一个分支上完成修改。
- 提交 Pull Request,并在描述里引用这个 Issue 编号。
devcontainers/cli 的其他 Issue
-
难度 2/5 1-3 小时 新手友好度 82/100
devcontainers/cli#1325 ·
维护者通常 1 天内回复
-
难度 1/5 1 小时以内 新手友好度 92/100
devcontainers/cli#1203 ·
维护者通常 1 天内回复
-
难度 1/5 1-3 小时 新手友好度 68/100
devcontainers/cli#1178 · 1 条评论 ·
维护者通常 1 天内回复
-
难度 3/5 半天 新手友好度 45/100
devcontainers/cli#1324 ·
维护者通常 1 天内回复
-
`devcontainer build` fails on Buildx 0.37.2 because the generated Dockerfile is outside the Compose bake context可能已有人在做 @v-Kaniska244 于 7 天前认领。 未关闭
devcontainers/cli#1320 · 1 条评论 · 6 个 reaction · 已指派 1 人 ·
维护者通常 1 天内回复
查看 devcontainers/cli 的全部 Issue
相似的 Issue
-
难度 2/5 1-3 小时 新手友好度 74/100
AvaProtocol/ava-sdk-js#276 ·
维护者通常 1 天内回复
-
难度 2/5 1-3 小时 新手友好度 75/100
apollographql/apollo-client#13493 ·
维护者通常 1 天内回复
-
Custom hosts written as trailing-dot FQDNs (`host.local.`) aren't detected as local backends可能已有人在做 @roboomp 今天认领。 未关闭bug prio:p2 providers triaged
难度 2/5 1-3 小时 新手友好度 82/100
can1357/oh-my-pi#15798 · 3 条评论 ·
维护者通常 1 天内回复
-
难度 2/5 1-3 小时 新手友好度 62/100
code-yeongyu/oh-my-openagent#10172 ·
维护者通常 1 天内回复
-
难度 2/5 1-3 小时 新手友好度 70/100
PDFCraftTool/pdfcraft#189 ·