vi docker-compose.yml
services:
<srv_name>:
image: <image_name>
container_name: <container_name>
hostname: <hostname>
restart: unless-stopped
environment:
TZ: "Europe/Moscow"
networks:
- default
networks:
default:
ipam:
driver: default
config:
- subnet: 172.28.0.0/16
services — основной раздел, где мы будем создавать и описывать наши сервисы (контейнеры docker).
В данном примере сервис один.
Для добавления еще одного добавляем еще строчки <srv_name>.
<srv_name> — название для нашего сервиса, на основе которого будет создан контейнер.
image — имя образа, который будет использоваться для создания контейнера.
container_name — имя, которое получен созданный контейнер.
hostname — имя хоста внутри контейнера.
restart — поведения контейнера при падении. В нашем примере мы указываем на необходимость автоматической перезагрузки, за исключением случаев, когда мы его сами остановили командой stop.
environment — задаем переменные окружения. В нашем примере только одна, которая указывает на часовой пояс (московское время).
networks — привязываем наш контейнер к сети. Опционально, но лучше определять самому подсеть. Это упрощает настройку некоторых сервисов, например, мы можем ограничить доступ для определенных подсетей и не желательно, чтобы подсети задавалась случайным образом.
networks — описание для сети. В нашем примере используются стандартные настройки, но указывается конкретная подсеть 172.28.0.0/16.
Сервисы
В данном разделе рассмотрим примеры настроек сервисов (контейнеров).
services:
<имя сервиса>:
<настройки сервиса>
image: nginx
build:
context: ./web-server/
args:
buildno: 22042001
build — указание на необходимость сборки из Dockerfile. Пример создания последнего читайте в инструкции Создание собственного образа Docker.
context — путь, где нужно искать Dockerfile относительно места, где находится docker-compose файл.
buildno — номер для сборки.
volumes:
- /data/mysql:/var/lib/mysql
Также мы можем смонтировать папку только на чтение, например:
volumes:
- /:/rootfs:ro
а) Ports (внешняя публикация). С помощью данной опции мы можем указывать, на каких портах должен слушать контейнер и на какие порты должны пробрасываться запросы:
ports:
- 8080:80
Или можно прописать так:
ports:
- 80
expose:
- 7000
environment:
TZ: "Europe/Moscow"
Чтобы передать несколько переменных, просто их перечисляем:
environment:
TZ: "Europe/Moscow"
MYSQL_ROOT_PASSWORD=password
Для каждого приложения есть свой набор системных переменных, которые оно понимает и интерпретирует. Например, MYSQL_ROOT_PASSWORD поймет СУБД и установит значение в качестве пароля для пользователя root.
Также системные переменные можно передать не в сценарии docker-compose, а в файле .env — просто создадим этот файл в одной директории с файлом docker-compose.yml:
vi .env
MYSQL_ROOT_PASSWORD=secret
MYSQL_PWD=secret
depends_on:
- db
command: [ "redis-server", "/usr/local/etc/redis/redis.conf" ]
Или можно написать так:
command:
- redis-server
- /usr/local/etc/redis/redis.conf
Но если нам понадобиться запустить несколько последовательных команд, рабочий вариант с использованием bash:
command: bash -c "yarn install && yarn start"
или если в контейнере нет bash:
command: sh -c "yarn install && yarn start"
labels:
MAINTAINER: ${MAINTAINER_EMAIL}
SITE_URL: ${SITE_URL}
user: root
working_dir: /var/www/app
Healthcheck
Данная директива, хоть и является частью сервиса, мы рассмотрим ее в отдельном разделе. Синтаксис:
services:
<имя сервиса>:
...
healthcheck:
test: <script>
interval: <interval>
timeout: <timeout>
retries: <retries>
test — наш скрипт, который должен вернуть 0, если все хорошо, или 1 — если все плохо.
interval — как часто запускать проверку.
timeout — как долго нужно ждать ответа.
retries — сколько раз тест должен вернуть отрицательный результат, чтобы контейнер перешел в состояние «unhealthy».
healthcheck:
test: curl -s http://127.0.0.1 | grep works
interval: 30s
timeout: 2s
retries: 10
healthcheck:
test: ["CMD", "mysql" ,"-h", "mysql", "-P", "3306", "-u", "root", "-e", "SELECT 1", "cache"]
interval: 30s
timeout: 2s
retries: 10
Отдельно рассмотрим варианты сетевых настроек.
Список сетей, созданных для docker можно увидеть командой:
docker network ls
Получить подробную информацию по сети можно командой:
docker network inspect <имя сети>
services:
<srv_name>:
networks:
- default
networks:
default:
ipam:
driver: default
config:
- subnet: 172.28.0.0/16
services:
<srv_name>:
networks:
default:
aliases:
- <alternative_name>
services:
<srv_name>:
networks:
- dnet
networks:
dnet:
external:
name: dnet
services:
<srv_name>:
networks:
vpcbr:
ipv4_address: 172.28.0.2
networks:
vpcbr:
driver: bridge
ipam:
config:
- subnet: 172.28.0.0/24
gateway: 172.28.0.1
services:
<srv_name>:
...
extra_hosts:
foo: 1.2.3.4
bar: 5.6.7.8
Рассмотрим различные примеры выполнения команды docker-compose.
docker-compose --version
docker-compose up -d
С указанием альтернатнативного файла docker-compose.
docker-compose -f /foo/bar/other-docker-compose.yml up -d
docker-compose up -d
Перечитать и пересобрать контейнеры, если есть инструкция build:
docker-compose up -d --build
Только остановить контейнеры:
docker-compose down
Остановить контейнеры с удаление данных (в volumes):
docker-compose down --volumes
Network <net-name>_default Error
Network <net-name>_default Error
failed to create network <net-name>_default: Error response from daemon: could not find an available,
non-overlapping IPv4 address pool among the defaults to assign to the network
Причина: при запуске композа автоматически создается сеть с суффиксом _default. Данная ошибка означает, что такую сеть не удалось создать, так как существует лимит на пулы IP-адресов и данный лимит был исчерпан.
Решение: быстрее всего выполнить чистку docker от неиспользуемых сетей. Для этого выполняем команду:
docker network prune