Hi! I have the following `BUILD` file that reprodu...
# general
f
Hi! I have the following
BUILD
file that reproduces the issue I'm having.
Copy code
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:
Copy code
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:
Copy code
╰─❯ 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:
Copy code
╰─❯ 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:
Copy code
╰─❯ 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?
e
1. Since
img-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:
Copy code
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.
Copy code
image_tags=[env("TAG_DST", "default-tag")]
and then run
TAG_DST=abc pants package //:img-code
This gives you more freedom to do things like setting env vars with your tags in CI job metadata, or using
.pants.bootstrap
to set them on pants invocation, etc.
f
Thanks a lot for the explanation and the hints! Will try it out.
👍 1