英文:
How to prevent overwriting the whole environment field while using YAML anchors
问题
我正在编写我的docker-compose.yml文件,为了避免编写冗余的行,特别是为了在开发、uat、生产等不同配置文件中使用不同的配置,我使用了YAML锚点。以下是我用于uat和dev的一个适配器示例。
Adapter:&Adapter
image: "my-image"
profiles:
- uat
environment:
- JAVA_OPTS="${JAVA_OPTS} -Dloader.main=com.my.class"
- SPRING_PROFILES_ACTIVE=uat
volumes:
- /local/path/to/logs:/logs
depends_on:
- some_image
Adapter-dev:
<<: *Adapter
profiles:
- dev
environment:
- SPRING_PROFILES_ACTIVE=dev
.env文件包含:
JAVA_OPTS=-Xmx3g -Xms3g
关键部分是JAVA_OPTS是必须的,为了正确运行应用程序。JAVA_OPTS存储在.env文件中,我在JAVA_OPTS变量上附加以指定我的主类。我刚刚发现,按照上面的方式做会完全覆盖环境变量,并且只传递SPRING_PROFILES_ACTIVE到我的Docker容器的环境变量。我期望的是只覆盖SPRING_PROFILES_ACTIVE,而保留JAVA_OPTS。如何在docker-compose.yml中只覆盖SPRING_PROFILES_ACTIVE而不覆盖JAVA_OPTS呢?
英文:
I am writing my docker-compose.yml file and to avoid writing redundant lines especially for using different profiles for dev, uat, prod etc, I was using yaml anchors. Here is a sample for one of the adapters I used for uat and for dev.
Adapter:&Adapter
image:"my-image"
profiles:
- uat
environment:
- JAVA_OPTS="${JAVA_OPTS} -Dloader.main=com.my.class"
- SPRING_PROFILES_ACTIVE=uat
volumes:
- /local/path/to/logs:/logs
depends_on:
- some_image
Adapter-dev:
<<: *Adapter
profiles:
- dev
environment:
- SPRING_PROFILES_ACTIVE=dev
.env file contains:
JAVA_OPTS=-Xmx3g -Xms3g
The key part is that the JAVA_OPTS is a must have in order to run properly. The JAVA_OPTS is stored in a .env file, and I append to the JAVA_OPTS variable to specify my main class. I just found out that doing it in the way above, it overwrites the environment entirely and only passes the SPRING_PROFILES_ACTIVE to my docker container's environment variables. What I expected would be that only SPRING_PROFILES_ACTIVE would be overwritten, but the JAVA_OPTS would be preserved. How can I only overwrite the SPRING_PROFILES_ACTIVE in my docker-compose.yml without overwriting the JAVA_OPTS?
答案1
得分: 1
这可能是我会使用Compose的支持多个Compose文件的情况,这些文件能够合并每个服务的设置。Compose的配置文件更适合用于选择要运行的服务,但不一定适用于控制如何运行它。
你可以有一个基本的docker-compose.yml
文件,列出了每个环境都需要的所有设置。
# docker-compose.yml
version: '3.8'
services:
adapter:
image: "my-image"
environment:
- JAVA_OPTS="${JAVA_OPTS} -Dloader.main=com.my.class"
volumes:
- /local/path/to/logs:/logs
depends_on:
- some_image
然后,你可以为每个环境创建一个文件,只需为该环境添加设置。
# docker-compose.uat.yaml
version: '3.8'
services:
adapter:
environment:
- SPRING_PROFILES_ACTIVE=uat
当你运行docker-compose
命令时,可以使用docker-compose -f
选项指定两个文件。请注意,你需要在每次docker-compose
调用时都指定这两个文件;设置一个$COMPOSE_FILE
环境变量可能会更容易。
docker-compose -f docker-compose.yml -f docker-compose.uat.yaml up -d
Compose工具有两个版本,一个是作为独立工具运行的旧版本,另一个是打包为docker
CLI扩展的新版本。这个设置将适用于这两个版本。
英文:
This might be a case where I'd use Compose's support for multiple Compose files, which are able to combine per-service settings. Compose profiles are better for selecting which service to run, but not necessarily for controlling how to run it.
You'd have a base docker-compose.yml
file that listed all of the settings that were required in every environment
# docker-compose.yml
version: '3.8'
services:
adapter:
image: "my-image"
environment:
- JAVA_OPTS="${JAVA_OPTS} -Dloader.main=com.my.class"
volumes:
- /local/path/to/logs:/logs
depends_on:
- some_image
Then you'd have a file per environment that added settings for only that environment
# docker-compose.uat.yaml
version: '3.8'
services:
adapter:
environment:
- SPRING_PROFILES_ACTIVE=uat
When you go to run docker-compose
commands, you can then specify both files using docker-compose -f
options. Note that you need to specify both files on every docker-compose
invocation; setting a $COMPOSE_FILE
environment variable may be a little easier.
docker-compose -f docker-compose.yml -f docker-compose.uat.yaml up -d
There are two versions of the Compose tooling, an older one that runs as a standalone tool and a newer one packaged as a docker
CLI extension. This setup will work with both of them.
答案2
得分: 1
在Compose中,您可以设置一个服务来扩展另一个服务。这与您在YAML锚点中所展示的基本相同,但它还允许您提供附加设置。
version: '2.4'
services:
adapter:
image: "my-image"
profiles: []
environment:
- JAVA_OPTS="${JAVA_OPTS} -Dloader.main=com.my.class"
volumes:
- /local/path/to/logs:/logs
adapter-uat:
extends:
service: adapter
profiles:
- uat
environment:
- SPRING_PROFILES_ACTIVE=uat
depends_on:
- some_image
adapter-dev:
extends:
service: adapter
profiles:
- dev
environment:
- SPRING_PROFILES_ACTIVE=dev
depends_on:
- some_image
depends_on:
文档中指出不会在extends:
服务中被重用,因此我已将其复制到每个特定环境的服务中。
Compose工具有两个版本。如果您正在使用较旧的版本(docker-compose --version
显示版本为1),请注意Compose文件格式版本3不包括extends:
;您需要在文件开头声明version: 2.x
,并且在文件格式版本3中无法使用一些与Swarm相关的功能。
英文:
In Compose you can set up one service to extend another. This does essentially what you're showing with YAML anchors, but it also lets you provide additional settings.
version: '2.4'
services:
adapter:
image: "my-image"
profiles: []
environment:
- JAVA_OPTS="${JAVA_OPTS} -Dloader.main=com.my.class"
volumes:
- /local/path/to/logs:/logs
adapter-uat:
extends:
service: adapter
profiles:
- uat
environment:
- SPRING_PROFILES_ACTIVE=uat
depends_on:
- some_image
adapter-dev:
extends:
service: adapter
profiles:
- dev
environment:
- SPRING_PROFILES_ACTIVE=dev
depends_on:
- some_image
depends_on:
is documented to not be reused in extends:
services, so I've copied it into each per-environment service here.
There are two versions of the Compose tool. If you are using the older version of the tool (docker-compose --version
says it's version 1) then be aware that the Compose file format version 3 doesn't include extends:
; you need to declare a version: 2.x
at the start of the file and you will be unable to use some Swarm-related features in version 3 of the file format.
答案3
得分: 0
特定的解决方案是使用common-services.yml文件。这允许我只运行具有指定配置文件的服务,而不运行默认服务。我所做的是将默认服务提取到一个额外的yml文件中,如下所示:
# common-services.yml:
services:
adapter:
image: "my-image"
profiles: []
environment:
- JAVA_OPTS="${JAVA_OPTS} -Dloader.main=com.my.class"
volumes:
- /local/path/to/logs:/logs
而Docker Compose YAML看起来如下:
# docker-compose.yml
version: '3.9'
services:
adapter-uat:
extends:
file: common-services.yml
service: adapter
profiles:
- uat
environment:
- SPRING_PROFILES_ACTIVE=uat
depends_on:
- some_image
adapter-dev:
extends:
file: common-services.yml
service: adapter
profiles:
- dev
environment:
- SPRING_PROFILES_ACTIVE=dev
depends_on:
- some_image
英文:
The specific solution used was to utilise a common-services.yml file. This allowed me to only run the services with the specified profile without running the default services. What I did was to extract the default service to an additional yml file like so:
#common-services.yml:
services:
adapter:
image: "my-image"
profiles: []
environment:
- JAVA_OPTS="${JAVA_OPTS} -Dloader.main=com.my.class"
volumes:
- /local/path/to/logs:/logs
and the docker compose yaml will look like:
#docker-compose.yml
version: '3.9'
services:
adapter-uat:
extends:
file: common-services.yml
service: adapter
profiles:
- uat
environment:
- SPRING_PROFILES_ACTIVE=uat
depends_on:
- some_image
adapter-dev:
extends:
file: common-services.yml
service: adapter
profiles:
- dev
environment:
- SPRING_PROFILES_ACTIVE=dev
depends_on:
- some_image
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论