3

I am currently building a container in my compose with a command

docker compose build --build-arg VAR_NAME=$(some_command) service_name

and I would like to build the same container with the simpler command docker compose build service_name, but I have not found a way to have docker compute the new output of some_command at each build.

To accomplish this I can freely change both the compose file and the Dockerfile for the container.

Is there any way to have docker instantiate a build argument or some other kind of variables dynamically on each build?

What I tried so far:

My first idea was to do something like the following

services:
    service_name:
        build:
            context: ./service_name
            args:
                VAR_NAME: $(some_command)

or

                VAR_NAME: "$(some_command)"

or

                VAR_NAME: "$$(some_command)"

but none of them works, even if

services:
    service_name:
        build:
            context: ./service_name
            args:
                VAR_NAME: 'example of some_command output'

works correctly.

2
  • i don't think you can set build args dynamically in a docker-compose file. i use build scripts for this. for example build.sh contains docker-compose build --build-arg MY_VAR=$(command) Commented Sep 12, 2022 at 11:52
  • How to set uid and gid in Docker Compose? discusses a similar problem (trying to set user: $(id -u)) and notes that you cannot do command substitution or other advanced shell substitutions in a Compose file. Commented Sep 12, 2022 at 12:52

2 Answers 2

4

it seems that docker does not support running shell commands in a docker-compose.yml

see the Using shell command in docker-compose.yml github discussion

you could use a script to wrap your build command.

# build.sh

docker-compose build --build-arg MY_VAR=$(command)
Sign up to request clarification or add additional context in comments.

2 Comments

In the future I might have containers that use similar build args with different per-container values. I guess I will have to rename them.
It looks heavy but it does work, thanks.
0

@tom's answer is likely better but out of stubbornness I decided to generate a docker-compose.ovverride.yml with the correct values.

I went for ad-hoc template processed with sed:

docker-compose.template:

services:
    admin:
        build:
            args:
                VAR_NAME: __VAR_NAME__
                VAR_NAME2: __VAR_NAME2__

and a simple sed script:

sed \
  -e "s/__VAR_NAME__/$(some_command)/g" \
  -e "s/__VAR_NAME2__/$(some_command2)/g" \
  ./docker-compose.template \
  > ./docker-compose.override.yml

This is quite ugly but works for my use-case

TODO:

  1. Fix escaping in sed's regex pattern, currently the output is in the pattern [0-9]+ so it is fine
  2. Use a better template language

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.