英文:
Common docker compose items as yaml fragments
问题
I want to clean up my docker-compose.yml
with yaml fragments.
x-common: &common
restart: unless-stopped
security_opt:
- no-new-privileges:true
volumes:
- /etc/localtime:/etc/localtime:ro
services:
myapp1:
<<: *common
image: app1
volumes:
- ./foo:/foo
myapp2:
<<: *common
image: app2
volumes:
- ./bar:/bar
When I run docker compose config
to show the final result, the common restart
and security_opt
items are applied. But the common volumes
item is not - I assume this is because the services are overwriting it.
Is there a way to do this?
英文:
I want to clean up my docker-compose.yml
with yaml fragments.
x-common: &common
restart: unless-stopped
security_opt:
- no-new-privileges:true
volumes:
- /etc/localtime:/etc/localtime:ro
services:
myapp1:
<<: *common
image: app1
volumes:
- ./foo:/foo
myapp2:
<<: *common
image: app2
volumes:
- ./bar:/bar
When I run docker compose config
to show the final result, the common restart
and security_opt
items are applied. But the common volumes
item is not - I assume this is because the services are overwriting it.
Is there a way to do this?
答案1
得分: 1
这是您提供的代码示例的中文翻译:
这个问题没有一个很好的解决方式。复杂的因素在于`volumes`是一个*列表*,而不是一个字典,而YAML没有合并列表的语法。
你可以尝试像这样做:
```yaml
x-common: &common
restart: unless-stopped
security_opt:
- no-new-privileges:true
x-common-volume: &volume /etc/localtime:/etc/localtime:ro
services:
myapp1:
<<: *common
image: app1
volumes:
- *volume
- ./foo:/foo
myapp2:
<<: *common
image: app2
volumes:
- *volume
- ./bar:/bar
这可以让你完成一半的工作 - 你需要记得将共同的卷添加到每个服务中,但你不必每次都重新输入完整的条目。
根据这个问题的严重程度,你可以考虑使用某种模板机制生成你的docker-compose.yml
文件 - 例如,使用jsonnet:
local Common = {
restart: 'unless-stopped',
security_opt: ['no-new-privileges:true'],
volumes: [
'/etc/localtime:/etc/localtime:ro',
]
};
{
services: {
myapp1: Common {
image: 'app1',
volumes+: [
'./foo:/foo',
],
},
myapp2: Common {
image: 'app2',
volumes+: [
'./bar:/bar',
],
},
},
}
通过运行jsonnet docker-compose.jsonnet > docker-compose.yaml
生成你的docker-compose.yml
文件,你就可以得到你想要的内容。
英文:
There's not really a great way to do this. The complicating factor is that volumes
is a list, rather than a dictionary, and YAML doesn't have a syntax for merging lists.
You could do something like this:
x-common: &common
restart: unless-stopped
security_opt:
- no-new-privileges:true
x-common-volume: &volume /etc/localtime:/etc/localtime:ro
services:
myapp1:
<<: *common
image: app1
volumes:
- *volume
- ./foo:/foo
myapp2:
<<: *common
image: app2
volumes:
- *volume
- ./bar:/bar
Which gets you halfway there -- you need to remember to add the common volume to each service, but you don't have to retype the full entry each time.
Depending on how much this bothers you, you could look into generating your docker-compose.yml
files with some sort of templating mechanism -- e.g., using jsonnet:
local Common = {
restart: 'unless-stopped',
security_opt: ['no-new-privileges:true'],
volumes: [
'/etc/localtime:/etc/localtime:ro',
]
};
{
services: {
myapp1: Common {
image: 'app1',
volumes+: [
'./foo:/foo',
],
},
myapp2: Common {
image: 'app2',
volumes+: [
'./bar:/bar',
],
},
},
}
Generating your docker-compose.yml
by running jsonnet docker-compose.jsonnet > docker-compose.yaml
and you've got what you want.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论