docker / compose

Define and run multi-container applications with Docker
https://docs.docker.com/compose/
Apache License 2.0
33.98k stars 5.23k forks source link

Request for allowing separate definition of image `tag` under `services` #11743

Closed oalagtash closed 2 weeks ago

oalagtash commented 6 months ago

Description

It would immensely helpful if I can define the tag of an image separately. This allows the use of YAML anchors and aliases in the compose.yml. Especially if the docker compose gets big and many images have the same tag name (special release).

For example: The following is currently not possible:

version: "3.9"

x-image-tag: &image-tag 2.0.0

services:
    my-image-a:
        image: my-image-a:*image-tag
    my-image-b:
        image: my-image-b:*image-tag

But it would be possible if:

version: "3.9"

x-image-tag: &image-tag 2.0.0

services:
    my-image-a:
        image: my-image-a
        tag:*image-tag
    my-image-b:
        image: my-image-b
        tag:*image-tag

Many Thanks!

ndeloof commented 6 months ago

The common approach to this issue is to define tag by a variable, maybe using a default value or with .env file to declare a reasonable default value:

services:
    my-image-a:
        image: my-image-a:${TAG:-dev}
oalagtash commented 6 months ago

Thanks for your response! I am aware of this approach. This only works if we have a .env file committed in git repo or an env variable maintained on each team member machine. Both ways are not practical, in my opinion. Having this feature would allow defining image tag as YAML alias und use YAML anchor to reference it.

ndeloof commented 6 months ago

Both ways are not practical, in my opinion.

that's the compose way ¯_(ツ)_/¯

oalagtash commented 6 months ago

Not a helpful response ^^

Assume you have 20 images sharing the same tag. And you have .env file locally with 20 lines of configured env variables. This .env you cannot push because it is developer specific. How would you handle a change of image tag? Wouldn't it be great if you have it defined at one place? Specifically in the compose.yml where the service is defined (like showed above)?

ndeloof commented 6 months ago

that's why compose file variables support default value syntax ${VAR:-default} so you don't need a value defined in your .env file to get a reasonable default being set (would typically be set to latest tag on current git branch, or such thing) and a developer still can override value

oalagtash commented 6 months ago

Yes I meant with Interpolation considered. You have ${VAR:-2.1.0} defined 20 times in compose.yml. Each time tag changes you will need to update the 20 places of ${VAR:-2.1.0} to ${VAR:-2.2.1}, while making sure not mistakenly changing unrelated image that might hold the same tag. In such cases, it is failure prune.

If tag: was to separate from image:, we could have one YAML alias x-image-tag: &image-tag 2.1.0. Changing this alias will only effect services referencing it.

oalagtash commented 6 months ago

Maybe even like this (did not test it but should work): x-image-tag: &image-tag ${VAR:-2.1.0}. This way we preserve the "compose way" :)

jhrotko commented 1 month ago

@oalagtash why not add the whole image+tag as an anchor? Since the tag is tightly related with the image?

ndeloof commented 1 month ago

I experimented with the ability to split image into sub-attributes on https://github.com/compose-spec/compose-go/pull/695 This has some impacts on type signature, so this will have some impact on docker compose codebase

This is just for evaluation purpose, I still consider - whenever this involves repetitions in the compose.yaml - this is a trivial task to search for ${VAR:-2.1.0} and replace with ${VAR:-2.2.0} on version bump, can be automated and as such has a minimal impact on our users, while keeping the compose/compose-go codebase simpler. But maybe this would enable some other use-cases ?

oalagtash commented 2 weeks ago

@oalagtash why not add the whole image+tag as an anchor? Since the tag is tightly related with the image?

Because we have +10 different images built with the same tag. This is the case when having a maven project with many modules. When built, all modules would share the same version, but different names.

I experimented with the ability to split image into sub-attributes on compose-spec/compose-go#695 This has some impacts on type signature, so this will have some impact on docker compose codebase

This is just for evaluation purpose, I still consider - whenever this involves repetitions in the compose.yaml - this is a trivial task to search for ${VAR:-2.1.0} and replace with ${VAR:-2.2.0} on version bump, can be automated and as such has a minimal impact on our users, while keeping the compose/compose-go codebase simpler. But maybe this would enable some other use-cases ?

It's a trivial task but failure prune specially when have a complex docker-compose file, because different images might share the same version, even if they are not related. For example, busybox:2, myimage:2 and mysecondimage:2. I need to have a well-maintained complex regex script or carefully change the tags manually to update tag 2 to 3 without changing busybox tag. Having a yaml anchor would solve this problem. Anyway, I do understand if this is cumbersome to implement.

ndeloof commented 2 weeks ago

@oalagtash if, as suggested, you use a variable ${MY_TAG:-2} to set tag for your own images with a default value, then search/replace is a trivial task, and you also can just set variable to switch to another tag.

I'm closing this issue as "not planned" as there's a trivial workaround that offers more flexibility