Применение DRY к docker-compose.yml
Apr 2, 2018 07:50 · 813 words · 4 minute read
Мы уже знаем, что файлы docker-compose.yml
- отличный способ определения нескольких сервисов (контейнеров), которые должны работать как единый стек. Но при большом количестве сервисов в файле неизменно появляются одинаковые, повторяющиеся для каждого контейнера блоки кода (описания) - давайте разберемся с ними!
Давайте применим принцип Don’t Repeat Yourself (DRY) к файлам docker-compose.yml
с использованием алиасов (aliases) и якорей (aliases) - встроенного функционала YAML.
С помощью якоря можно определить элемент в документе YAML, а затем ссылаться на этот элемент (используя алиас) позже в том же документе. Якорь можно обозначить с помощью символа &
, алиас - с помощью символа *
. Ниже приведен пример YAML-файла с якорем и алиасом:
base: &base
name: Everyone has same name
foo:
<<: *base
age: 10
bar:
<<: *base
age: 20
После прочтения файла парсером YAML результат будет следующим:
foo:
name: Everyone has same name
age: 10
bar:
name: Everyone has same name
age: 20
Использование якорей и алиасов “в чистом” виде в конфигурационных файлах docker-compose.yml
ранее было несколько неудобным и неочевидным, однако начиная с версии 3.4 добавлена поддержка расширенных полей (или полей расширений - extension fields). Теперь любой ключ верхнего уровня, начинающийся с x-
в файле docker-compose.yml
, будет проигнорирован утилитой docker-compose и самим Docker Engine. Такие расширения можно использовать для определения части сервиса, содержащей только общие параметры.
Рассмотрим конкретный пример. Ранее файле docker-compose.yml
, описывающий стек сервисов для деплоя в docker swarm (подробнее здесь, здесь и тут) выглядел так:
version: '3.1'
services:
### PHP-FPM ########################################################
php-fpm:
image: registry.gitlab.lc:5000/develop/ed/php-fpm-ed-sq:staging
volumes:
- developcode:/var/www/develop
- static:/var/www/static
deploy:
replicas: 4
update_config:
parallelism: 1
delay: 10s
restart_policy:
condition: on-failure
placement:
constraints: [node.role == manager]
logging:
driver: gelf
options:
gelf-address: "udp://${GRAYLOG_ADDR}:12201"
tag: "php-fpm"
### Nginx ##########################################################
nginx:
image: registry.gitlab.lc:5000/develop/ed/nginx-ed-sq:staging
volumes:
- developcode:/var/www/develop
- static:/var/www/static
ports:
- "80:80"
- "443:443"
deploy:
replicas: 4
update_config:
parallelism: 1
delay: 10s
restart_policy:
condition: on-failure
placement:
constraints: [node.role == manager]
### SDCV ###########################################################
sdcv:
image: registry.gitlab.lc:5000/develop/ed/sdcv-ed-sq:latest
ports:
- "9095:9095"
deploy:
replicas: 1
update_config:
parallelism: 1
delay: 1s
restart_policy:
condition: on-failure
placement:
constraints: [node.role == manager]
logging:
driver: gelf
options:
gelf-address: "udp://${GRAYLOG_ADDR}:12201"
tag: "sdcv"
### Redis ##########################################################
redis:
image: registry.gitlab.lc:5000/develop/ed/redis-ed-sq:latest
volumes:
- redis:/data
ports:
- "6379:6379"
deploy:
replicas: 1
update_config:
parallelism: 1
delay: 1s
restart_policy:
condition: on-failure
placement:
constraints: [node.role == manager]
logging:
driver: gelf
options:
gelf-address: "udp://${GRAYLOG_ADDR}:12201"
tag: "redis"
### Memcached ######################################################
memcached:
image: registry.gitlab.lc:5000/develop/ed/memcached-ed-sq:latest
volumes:
- memcached:/var/lib/memcached
ports:
- "11211:11211"
deploy:
replicas: 1
update_config:
parallelism: 1
delay: 1s
restart_policy:
condition: on-failure
placement:
constraints: [node.role == manager]
logging:
driver: gelf
options:
gelf-address: "udp://${GRAYLOG_ADDR}:12201"
tag: "memcached"
### Websocket ######################################################
websocket:
image: registry.gitlab.lc:5000/develop/ed/websocket-ed-sq:latest
env_file: .env.staging.lc
ports:
- "8092:8092"
deploy:
replicas: 1
update_config:
parallelism: 1
delay: 1s
restart_policy:
condition: on-failure
placement:
constraints: [node.role == manager]
logging:
driver: gelf
options:
gelf-address: "udp://${GRAYLOG_ADDR}:12201"
tag: "websocket"
### Monitoring: node-exporter ######################################
nodeexporter:
image: prom/node-exporter:v0.14.0
volumes:
- /proc:/host/proc:ro
- /sys:/host/sys:ro
- /:/rootfs:ro
command:
- '-collector.procfs=/host/proc'
- '-collector.sysfs=/host/sys'
- '-collector.filesystem.ignored-mount-points=^/(sys|proc|dev|host|etc)($$|/)'
ports:
- "9100:9100"
deploy:
mode: global
restart_policy:
condition: on-failure
labels:
org.label-schema.group: "monitoring"
### Monitoring: cAdvisor ###########################################
cadvisor:
image: google/cadvisor:v0.26.1
volumes:
- /:/rootfs:ro
- /var/run:/var/run:rw
- /sys:/sys:ro
- /var/lib/docker/:/var/lib/docker:ro
ports:
- "9200:8080"
deploy:
mode: global
restart_policy:
condition: on-failure
labels:
org.label-schema.group: "monitoring"
### Volumes Setup ##################################################
volumes:
developcode:
external:
name: code-${VER}
memcached:
driver: "local"
redis:
driver: "local"
static:
driver: "local"
driver_opts:
type: nfs
o: addr=192.168.0.218,rw
device: ":/srv/static"
Применяя принцип DRY данный файл получилось привести к следующему виду:
version: '3.4'
# Global logging options
# Customizing TAG: https://docs.docker.com/config/containers/logging/log_tags/
x-logging: &logging
logging:
driver: gelf
options:
gelf-address: "udp://${GRAYLOG_ADDR:-graylog.lc}:12201"
tag: "{{.Name}}"
x-deploy-tmpl: &deploy-tmpl
deploy:
replicas: 1
update_config:
parallelism: 1
delay: 1s
restart_policy:
condition: on-failure
placement:
constraints: [node.role == manager]
x-deploy-repl: &deploy-repl
deploy:
replicas: 4
update_config:
parallelism: 1
delay: 1s
restart_policy:
condition: on-failure
placement:
constraints: [node.role == manager]
x-monitoring-tmpl: &monitoring-tmpl
deploy:
mode: global
restart_policy:
condition: on-failure
labels:
org.label-schema.group: "monitoring"
services:
### PHP-FPM ########################################################
php-fpm:
image: registry.gitlab.lc:5000/develop/ed/php-fpm-ed-sq:staging
volumes:
- developcode:/var/www/develop
- static:/var/www/static
<<: *deploy-repl
<<: *logging
### Nginx ##########################################################
nginx:
image: registry.gitlab.lc:5000/develop/ed/nginx-ed-sq:staging
volumes:
- developcode:/var/www/develop
- static:/var/www/static
ports:
- "80:80"
- "443:443"
<<: *deploy-repl
### SDCV ###########################################################
sdcv:
image: registry.gitlab.lc:5000/develop/ed/sdcv-ed-sq:latest
ports:
- "9095:9095"
<<: *deploy-tmpl
<<: *logging
### Redis ##########################################################
redis:
image: redis:4.0-alpine
command:
- 'redis-server'
- '--loglevel ${REDIS_LOGLEVEL:-warning}'
- '--databases 2'
- '--save 300 1'
- '--save 60 1000'
- '--maxmemory ${REDIS_MAXMEM:-50mb}'
- '--maxmemory-policy ${REDIS_POLICY:-noeviction}'
- '--requirepass ${REDIS_PASS}'
volumes:
- redis:/data
ports:
- "6379:6379"
<<: *deploy-tmpl
<<: *logging
### Memcached ######################################################
memcached:
image: memcached:1.5-alpine
volumes:
- memcached:/var/lib/memcached
ports:
- "11211:11211"
<<: *deploy-tmpl
<<: *logging
### Websocket ######################################################
websocket:
image: registry.gitlab.lc:5000/develop/ed/websocket-ed-sq:latest
env_file: .env.staging.lc
ports:
- "8092:8092"
<<: *logging
### Monitoring: node-exporter ######################################
nodeexporter:
image: prom/node-exporter:v0.15.2
volumes:
- /proc:/host/proc:ro
- /sys:/host/sys:ro
- /:/rootfs:ro
command:
- '--path.procfs=/host/proc'
- '--path.sysfs=/host/sys'
- '--collector.filesystem.ignored-mount-points=^/(sys|proc|dev|host|etc)($$|/)'
ports:
- "9100:9100"
<<: *monitoring-tmpl
### Monitoring: cAdvisor ###########################################
cadvisor:
image: google/cadvisor:v0.29.0
volumes:
- /:/rootfs:ro
- /var/run:/var/run:rw
- /sys:/sys:ro
- /var/lib/docker/:/var/lib/docker:ro
ports:
- "9200:8080"
<<: *monitoring-tmpl
### Volumes Setup ##################################################
volumes:
developcode:
external:
name: code-${VER}
memcached:
driver: "local"
redis:
driver: "local"
static:
driver: "local"
driver_opts:
type: nfs
o: addr=192.168.0.218,rw
device: ":/srv/static"
При упрощении своих конфигурационных файлов docker-compose.yml
не забывайте проверять их синтаксис используя команду docker-compose config
, как я уже советовал ранее.