fierce-greece-10087
01/14/2025, 1:09 PMBUILD
file that reproduces the issue I'm having.
docker_image(
name="img-base",
instructions=[
"FROM python:3.11.10-slim-bookworm",
],
registries = [
"some-registry"
],
image_tags=["{build_args.TAG_DST}"],
)
docker_image(
name="img-code",
dependencies=[
":img-base",
],
instructions=[
"ARG TAG_SRC",
"FROM some-registry/img-base:${TAG_SRC}",
],
registries = [
"some-registry"
],
image_tags=["{build_args.TAG_DST}"],
)
Now I'm not sure whether my whole thinking is wrong and I perhaps shouldn't expect pants
to work like this, but here we go ...
I would first run the following:
pants package //:img-base --docker-build-args="['TAG_DST=abc']"
pants package //:img-code --docker-build-args="['TAG_SRC=abc', 'TAG_DST=abc']"
Now when I list docker images, I see what I expect:
╰─❯ docker images --filter=reference='some-registry/*'
REPOSITORY TAG IMAGE ID CREATED SIZE
some-registry/img-base abc 80abb94774d6 2 months ago 129MB
some-registry/img-code abc 80abb94774d6 2 months ago 129MB
Now when I want to build img-code:def
from img-base:abc
, pants still goes building img-base:def
, even if it doesn't need it:
╰─❯ pants package //:img-code --docker-build-args="['TAG_SRC=abc', 'TAG_DST=def']"
14:05:11.31 [INFO] Completed: Building docker image some-registry/img-base:def
14:05:11.31 [INFO] Completed: Building docker image some-registry/img-code:def
14:05:11.31 [INFO] Wrote dist/img-code.docker-info.json
Built docker image: some-registry/img-code:def
Docker image ID: sha256:80abb94774d660831663290fe0b208b3e067b88647902f0f9e1d3a331a997afd
Docker images now look like this:
╰─❯ docker images --filter=reference='some-registry/*'
REPOSITORY TAG IMAGE ID CREATED SIZE
some-registry/img-base abc 80abb94774d6 2 months ago 129MB
some-registry/img-base def 80abb94774d6 2 months ago 129MB
some-registry/img-code abc 80abb94774d6 2 months ago 129MB
some-registry/img-code def 80abb94774d6 2 months ago 129MB
Should pants
skip building img-base:def
here?elegant-florist-94385
01/14/2025, 2:07 PMimg-code
depends on img-base
, pants has determined that it needs to build img-base
before building img-code
.
2. Because you're passing `TAG_DST`(I know its intended for img-code
, but still), pants rebuilt (probably pulled from cache and re-tagged) img-base
as well.
3. If you use different vars for the tags in each image, what you'll probably see here is that the unexpected img-base
gets tagged with a null value (or is this an error), because its own specific var didn't get passed
4. If you remove the explicit `dependencies=[":img-base"]`from img-code
, I expect this would not occur at all, as there would be no dependency link causing pants to build img-base
However, the best way to fix this would be to do something like:
instructions=[
"ARG BASE_IMAGE=:img-base",
"FROM $BASE_IMAGE",
]
Notice that I set the var to supply the whole image (instead of just the tag), and I actually provide the default value as the "pants name" of the target, rather than the built image as it ends up in docker.
Then, you can remove the explicit dependency on img-base
since pants will be able to infer it by reading that ARG. Pants will do all the necessary substitution to make this work correctly at build time.
Now, you can just run pants package //:img-code
and pants will automatically build the base image if necessary, or pull it from cache if it is already there.
Also, instead of trying to pass TAG_DST as a build arg (since its not actually part of the docker build), you can use pants' own env substitution.
image_tags=[env("TAG_DST", "default-tag")]
and then run TAG_DST=abc pants package //:img-code
elegant-florist-94385
01/14/2025, 2:08 PM.pants.bootstrap
to set them on pants invocation, etc.fierce-greece-10087
01/15/2025, 8:05 AM