Two questions on the `docker_image` target: 1. How...
# general
t
Two questions on the
docker_image
target: 1. How can I target a Dockerfile with the
source
fild that is not relative to the BUILD file or any subdirectoy but is one level up, i.e.
../Dockerfile
? 2. I have seen that in a BUILD file I can reference values from the
pants.toml
like
repository="{build_argsREPO_URL}"
. Is it possible to get the name of the directory where the BUILD file is located in, such that I can do something like:
extra_build_args=["{THIS_DIRECTORY_NAME}"]
?
n
1. Also was trying to do this ... Don't believe it's possible. You can use relative references in the same build file, but otherwise have to give the full path - e.g.
src/main/docker/my-image:target-name
coke 1
c
2. Yes, you can use
build_file_dir()
as a function call. If embedded in a string value, use f-string
f"some text {build_file_dir()} more text"
👀 1
for 1, you’d have to move your
docker_image
target, is that feasible for you?
t
Mhh not sure, to give you a little bit of context: I have this structure:
Copy code
/services
  Dockerfile
  /serviceA
  /serviceB
All services share the same Dockerfile and the BUILD file for each service looks like this:
Copy code
docker_image(
    name="service-a-image",
    source="../Dockerfile",
    dependencies=[":lambda", "//:entrypoint"],
    repository="{build_args.REPO_URL}",
    image_tags=["latest"],
    # TODO: can this solved another way? it is due to the lambda.zip
    context_root="",
    extra_build_args=[f"SERVICE={build_file_dir()}]
)

python_awslambda(
    name="lambda",
    runtime="python3.8",
    handler="lambda_handler.py:handler",
)

python_sources()
Any idea how to restructure this? There will be a few services which will have a different docker_image target as they need another dockerfile, but for most of them it looks the same.
c
It’ll be a little more boiler plate, I think, but you could wrap that in a macro, strawman:
Copy code
# services/BUILD
service_image(
  name="service-a-image",
  service="serviceA",
)
service_image(
  name="service-b-image",
  service="serviceB",
)
Copy code
# pants macro file
def service_image(name, service, **kwargs):
  path = f"{build_file_dir()}/{service}"
  docker_image(
    name=name,
    source="Dockerfile",  # may be left out now as it's default
    dependencies=[f"{path}:lambda", "//:entrypoint"],
    extra_build_args=[f"SERVICE={path}"],
    ...,
    **kwargs
  )
only concern being if Pants will complain about multiple owners for the `Dockerfile`…?
t
That looks really good, gave it a first try. Few questions came up: 1. There is no way to use imports in macros? Would be great to do something like os.environ[''] 2. Can you think of a better way to pass a build arg from outside? Currently it is: export from my other programm to env
REPO_URL
, add this as entry to
build_args
in
pants.toml
, then use
repository="{build_args.REPO_URL}"
in the macro.
3. How can I run all
service_image
targets at the same time?
c
1. Sorry, no. Macros are restricted sandboxes, so no imports. 2. Nope, that sums it up as it is currently. 3. Oh,
./pants run
is an interactive process and support a single target only.
There’s been discussions about support things like
docker-compose
but I’ve not seen/done anything in that area with pants (yet?)
regarding running your services, best bet is to either run them outside of Pants entirely (after building them) or have some wrapper script, that depends on your service images and runs them from there (using
experimental_run_shell_command
for instance). On a recent version of Pants, there are docker image metadata available in the
dist
folder with details on all the image names etc, useful for building the docker run command…
t
3. But I can do something like this?
Copy code
./pants --target-type=service_image | \
  xargs ./pants package
I am pushing the images to Localstack ECR and will run them from there 🙂
@curved-television-6568 How can i register that new target I addes as a macro? So I can filter for that target-type
Found a solution: Use a tag 🙂
💯 1
c
Awesome. As macros aren’t really types, only functions that may define targets of existing types, it’s not a construct you can filter on directly, so you found a perfect solution for it! 🙂