В данной инструкции мы приведем различные примеры по работе с docker-compose без подробного описания принципа работы. Данный материал можно использовать в качестве шпаргалки.
Проброс папок и томов в Docker решает следующие проблемы, позволяя монтировать директории хоста внутри контейнера либо создавая централизованное хранилище. Таким образом мы получаем следующие преимущества:
- Мы не копируем данные, они хранятся в одно месте для всех контейнеров
- Раньше копирование отнимало время, а сейчас это делать не нужно, контейнеры запускаются быстрее
- У нас появляется больше возможностей для управления данными
- Что такое Docker Volumes
- Минуточку внимания
- Пересоздадим существующую структуру
- Версии
- Version 1
- Version 2
- Upgrading
- Networks
- Запуск docker-compose
- Healthcheck
- Читайте также
- Установка Docker Compose
- Файл docker-compose. yml
- Руководство по Docker Compose файлу
- Руководство по конфигурации сервисов
- build
- context
- dockerfile
- args
- cap_add, cap_drop
- command
- cgroup_parent
- container_name
- devices
- depends_on
- dns
- dns_search
- tmpfs
- entrypoint
- env_file
- environment
- expose
- extends
- external_links
- image
- labels
- links
- logging
- log_driver
- log_opt
- net
- network_mode
- networks
- aliases
- ipv4_address, ipv6_address
- pid
- ports
- security_opt
- stop_signal
- ulimits
- volumes, volume_driver
- volumes_from
- cpu_shares, cpu_quota, cpuset, domainname, hostname, ipc, mac_address, mem_limit, memswap_limit, privileged, read_only, restart, shm_size, stdin_open, tty, user, working_dir
- Инструкция VOLUME в Dockerfile
- Возможные ошибки
- Network <net-name>_default Error
- Сервисы
- Variable substitution
- Порты контейнера
- Базовый шаблон
- Типы томов Docker
- Создание Volumes через docker run
- Папки и файлы
- Подключение volume
- Создание Volumes через Dockerfile
- Создание Volumes через docker-compose
- Использование внешних томов
- Создание тома в другой директории
- Монтирование через Tmpfs
- Просмотр привязанных томов
- Привязка томов из другого контейнера
- Создание и удаление Volume
- Network configuration reference
- driver
- driver_opts
- ipam
- external
- Volume configuration reference
- driver
- driver_opts
- external
Что такое Docker Volumes
Том — это файловая система, которая расположена на хост-машине за пределами контейнеров. Тома представляют собой средства для постоянного хранения информации и могут совместно использоваться разными контейнерами. Созданием и управлением томами занимается Docker.
Попробуем просто создать несколько томов:
docker volume create --name data-www docker volume create --name data-sql docker volume create --name data-tmp
Для того, чтобы просмотреть список томов:
docker volume ls
DRIVER VOLUME NAME
local data-sql
local data-tmp
local data-www
Посмотреть информацию об отдельном томе:
docker volume inspect data-www
[
{
"CreatedAt": "2020-03-20T14:44:01+03:00",
"Driver": "local",
"Labels": {},
"Mountpoint": "/var/lib/docker/volumes/data-www/_data",
"Name": "data-www",
"Options": {},
"Scope": "local"
}
]
Если том больше не нужен, его можно удалить:
docker volume rm data-tmp
Чтобы удалить все тома, которые не используются контейнерами:
docker volume prune
Теперь смонтируем том data-www
при запуске контейнера:
docker run -it -v data-www:/var/www ubuntu:latest
Если вспомнить, что данные тома находятся в /var/lib/docker/volumes/data-www/_data
, то теперь в этой директории есть поддиректория html
, а внутри поддиректории — файл index.php
.
Данная команда разворачивает все три сервиса используя конфигурацию из файлов docker-compose.yml и docker-compose.prod.yml (но не из конфигурации для разработки docker-compose.override.yml).
Есть несколько частей Compose, которые имеют дело с переменными окружения в том или ином смысле. Эта страница поможет вам найти нужную информацию.
В оболочке можно использовать переменные среды для заполнения значений внутри файла Compose:
Так же как и в docker run -e, вы можете задать переменные окружения в контейнере с помощью docker-compose run -e:
Вы так же можете передать переменную из shell если не будете задавать ее значение:
Вы можете установить значения по умолчанию для любых переменных среды, указанных в Compose файле или использовать для настройки Compose файл среды с именем .env:
Когда вы запускаете docker-compose up, сервис web определенный выше использует образ webapp:v1.5. Вы можете убедиться в этом с помощью команды настроек, которая выводит настройки вашего приложения в терминал:
Значения из оболочки имеют приоритет над переменными из .env файла. Если вы установите TAG в другое значение в вашей оболочке, будет произведена следующая подстановка:
$ export TAG=v2.0
$ docker-compose config
version: '2.0'
services:
web:
image: 'webapp:v2.0'
version: '3'
services:
php:
volumes:
- "./web:/var/www/html"
Chown для ./web — root:root, пользователь www-data внутри контейнера не имеет прав на эту папку. Вероятно, нужно создать специального пользователя/группу с правами на эту папку и как-то передать его внутрь контейнера, но я не вижу в описании ключей для docker-compose.yml подходящего.
-
Вопрос заданболее трёх лет назад
Это не вольюм это маунт и права на нем тежи, что и на ./web.
Поставь локально chmod 777 или монтируй /etc/passwd /etc/shadow и кастомайз контейнер, чтоб uid gid с хостом совпадали.
я в похожем случае в контейнер прокидывал /etc/passwd и /etc/groups
после этого связка имя-uid группа-gid работает.
Макс, не получается. После прописывания группы и пользователя сервер вообще перестает отвечать. С дописками по Вашей схеме (если, конечно, я ее верно понял) выходит вот так:
version: '3'
services:
web:
image: nginx:alpine
volumes:
- "./etc/nginx/default.conf:/etc/nginx/conf.d/default.conf"
- "./etc/ssl:/etc/ssl"
- "./web:/var/www/html"
- "./etc/nginx/default.template.conf:/etc/nginx/conf.d/default.template"
- "/etc/passwd:/etc/passwd"
- "/etc/groups:/etc/groups"
ports:
- "80:80"
- "3000:443"
environment:
- NGINX_HOST=${NGINX_HOST}
command: /bin/sh -c "envsubst '$$NGINX_HOST' < /etc/nginx/conf.d/default.template > /etc/nginx/conf.d/default.conf && nginx -g 'daemon off;'"
restart: always
user: "1001:1001"
depends_on:
- php
- mysqldb
php:
build:
context: .
dockerfile: DockerfilePhpWithGit
restart: always
user: "1001:1001"
volumes:
- "./etc/php/php.ini:/usr/local/etc/php/conf.d/php.ini"
- "./web:/var/www/html"
- "/etc/passwd:/etc/passwd"
- "/etc/groups:/etc/groups"
где 1001:1001 — пользователь www-data:www-data. Пользователь с таким же именем и группой создается в сервисе php
Я в такой ситуации в entrypoint.sh контейнера модифицировал локальных пользователей, получая uid из прав смонтированного каталога:
SRC_DIR=/path/to/mounted/volume
DIR=/path/to/dir
USER=www-data
GROU=www-data
$uid=$(stat -c '%u' $SRC_DIR)
$gid=$(stat -c '%g' $SRC_DIR)
echo $uid > /root/uid
echo $gid > /root/gid
usermod -u $uid $USER
groupmod -g $gid $GROUP
mkdir -p $DIR
chown -R $USER:$GROUP $DIR
05 июл. 2023, в 15:59
1500 руб./за проект
05 июл. 2023, в 15:57
600 руб./в час
05 июл. 2023, в 15:53
1500 руб./в час
Минуточку внимания
В docker compose volumes — логические тома, которые задаются для каждого контейнера. Это директива в файле, определяющая связь точки монтирования на диске с другой точкой монтирования в контейнере.
Все, что находится в volumes сохраняется на диске после удаления контейнера. Остальные данные хранятся в памяти.
Основное предназначение Docker в быстром разворачивании окружения на любой машине из готовых образов, которые можно дорабатывать. Контейнер — временная структура, все изменения выполненные в нем существуют пока существует сам контейнер. На диске данные не сохраняются если они не вынесены в постоянную структуру — volume.
Для примера возьмем с dockerhub инструкцию для образа с wordpress, в немного измененном виде будем использовать ее.
Проект будет представлять собой сайт на wordpress с базой данных MySQL.
Сразу создадим каталоги под сайт и базу на хост машине. За счет биндинга они будут связаны с контейнерами
mkdir -p /home/site/db
На машине должны быть установлены сам Docker и docker-compose. Создаем docker-compose.yml
cd /home && mcedit docker-compose.yml
version: '2' services: wordpress: image: wordpress restart: always ports: - 8080:80 environment: WORDPRESS_DB_PASSWORD: example links: - mysql:db volumes: - /home/site:/var/www/html mysql: image: mysql:5.7 restart: always environment: MYSQL_ROOT_PASSWORD: example volumes: - /home/site/db:/var/lib/mysql
В файле 2 сервиса. Структура типовая, 80 порт из контейнера пробрасывается на порт 8080 хост машины. Используются стандартные образы с dockerhub.
Для каждого контейнера заданы блоки volumes:
— /home/site:/var/www/html для сайта
— /home/site/db:/var/lib/mysql для базы данных
Они определяют, что данные из временной структуры — контейнера будут сохраняться на хост машине.
Содержимое /var/www/html в /home/site, содержимое /var/lib/mysql в /home/site/db
Эта информация будет изменена при жизни контейнера и останется на хост машине после его удаления.
docker-compose -f docker-compose.yml up -d
Они успешно стартовали, с хоста обращаться к сервису можно только по порту 8080, на который пробрасываются запросы.
В браузере обратившись к IP адресу серверу и порту 8080 можно запустить установку CMS, затем попасть в административный раздел.
Внесем минимальные изменения в структуру перового поста. Поменяем заголовок ‘Hello World’ на ‘Hello Docker‘ и единственное существующее по-умолчанию предложение.

Пересоздадим существующую структуру
И удаляем их
Контейнеров нет, с ключем -a выводятся все контейнеры, в т.ч. незапущенные
docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
Файлы при этом сохранены на диске
Также как и содержимое /var/lib/mysql из контейнера
auto.cnf ca.pem client-key.pem ibdata1 ib_logfile1 performance_schema public_key.pem server-key.pem wordpress
ca-key.pem client-cert.pem ib_buffer_pool ib_logfile0 mysql private_key.pem server-cert.pem sys
При обращении к тому же URL:8080 сейчас будет возникать ошибка — веб-сервер, являющийся частью контейнера не работает.
Запускаем контейнеры через docker-compose вновь
docker-compose -f docker-compose.yml up -d
Creating home_mysql_1
Creating home_wordpress_1
Сейчас можно убедиться в том, что сайт вновь стал открываться и контент отображается в том же виде. При старте информация из docker-compose.yml считалась.
Были задействованы те же каталоги, что использовались ранее, с имеющимися данными.
Читайте про управление контейнерами вручную. При использовании docker compose volumes задаются в файле, при ручном создании контейнера их можно указывать с ключем -v.
Версии
There are two versions of the Compose file format:
- Version 1, the legacy format. This is specified by omitting a version key at the root of the YAML.
- Version 2, the recommended format. This is specified with a version: ‘2’ entry at the root of the YAML.
To move your project from version 1 to 2, see the Upgrading section.
Several things differ depending on which version you use:
- The structure and permitted configuration keys
- The minimum Docker Engine version you must be running
- Compose’s behaviour with regards to networking
These differences are explained below.
Version 1
Compose files that do not declare a version are considered “version 1”. In those files, all the services are declared at the root of the document.
Version 1 is supported by Compose up to 1.6.x. It will be deprecated in a future Compose release.
web:
build: .
ports:
- "5000:5000"
volumes:
- .:/code
links:
- redis
redis:
image: redis
Version 2
Compose files using the version 2 syntax must indicate the version number at the root of the document. All services must be declared under the services key.
Version 2 files are supported by Compose 1.6.0+ and require a Docker Engine of version 1.10.0+.
Named volumes can be declared under the volumes key, and networks can be declared under the networks key.
version: '2'
services:
web:
build: .
ports:
- "5000:5000"
volumes:
- .:/code
redis:
image: redis
A more extended example, defining volumes and networks:
version: '2'
services:
web:
build: .
ports:
- "5000:5000"
volumes:
- .:/code
networks:
- front-tier
- back-tier
redis:
image: redis
volumes:
- redis-data:/var/lib/redis
networks:
- back-tier
volumes:
redis-data:
driver: local
networks:
front-tier:
driver: bridge
back-tier:
driver: bridge
Upgrading
In the majority of cases, moving from version 1 to 2 is a very simple process:
- Indent the whole file by one level and put a services: key at the top.
- Add a version: ‘2’ line at the top of the file.
It’s more complicated if you’re using particular configuration features:
-
dockerfile: This now lives under the build key:
build: context: . dockerfile: Dockerfile-alternate
-
log_driver, log_opt: These now live under the logging key:
logging: driver: syslog options: syslog-address: "tcp://192.168.0.42:123"
-
links with environment variables: As documented in the environment variables reference, environment variables created by links have been deprecated for some time. In the new Docker network system, they have been removed. You should either connect directly to the appropriate hostname or set the relevant environment variable yourself, using the link hostname:
web: links: - db environment: - DB_PORT=tcp://db:5432
-
external_links: Compose uses Docker networks when running version 2 projects, so links behave slightly differently. In particular, two containers must be connected to at least one network in common in order to communicate, even if explicitly linked together.
Either connect the external container to your app’s default network, or connect both the external container and your service’s containers to an external network.
-
net: This is now replaced by network_mode:
net: host -> network_mode: host net: bridge -> network_mode: bridge net: none -> network_mode: none
net: "container:web" -> network_mode: "service:web"
net: "container:cont-name" -> network_mode: "container:cont-name" net: "container:abc12345" -> network_mode: "container:abc12345"
-
volumes with named volumes: these must now be explicitly declared in a top-level volumes section of your Compose file. If a service mounts a named volume called data, you must declare a data volume in your top-level volumes section. The whole file might look like this:
version: '2' services: db: image: postgres volumes: - data:/var/lib/postgresql/data volumes: data: {}
By default, Compose creates a volume whose name is prefixed with your project name. If you want it to just be called data, declare it as external:
volumes: data: external: true
Networks
Отдельно рассмотрим варианты сетевых настроек.
Список сетей, созданных для docker можно увидеть командой:
docker network ls
Получить подробную информацию по сети можно командой:
docker network inspect <имя сети>
1. Указать определенную подсеть. Задается с помощью опции subnet в отдельной секции networks. В последней мы создаем конфигурацию для определенной сети (в данном примере, default). Для конкретного сервиса мы также задаем привязку к созданной сети default в подразделе networks:
networks:
default:
ipam:
driver: default
config:
— subnet: 172.28.0.0/16
* где 172.28.0.0/16 — подсеть, в которой будут работать все контейнеры, которые привязаны к созданной сети default.
2. Алиасы. Данная настройка позволит видеть контейнеры по альтернативным именам (по умолчанию, они обнаруживаются по имени контейнера). Настройка указывается в подразделе networks сервиса:
* в данном примере наш контейнер будет также резолвиться по имени <alternative_name>.
3. Внешняя сеть. Если необходимо, чтобы наши контейнеры могли видеть по сети другие контейнеры, создаем сеть external:
networks:
dnet:
external:
name: dnet
networks:
vpcbr:
driver: bridge
ipam:
config:
— subnet: 172.28.0.0/24
gateway: 172.28.0.1
* в нашем примере будет создана подсеть 172.28.0.0/24, а контейнеру будет присвоен адрес 172.28.0.2.
* в данном примере имени foo будет соответствовать адрес 1.2.3.4, а bar — 5.6.7.8.
Запуск docker-compose
Рассмотрим различные примеры выполнения команды docker-compose.
1. Посмотреть версию:
2. Создание и запуск контейнеров:
docker-compose up -d
* напомним, что в текущем каталоге находится созданный файл с названием docker-compose.yml.
С указанием альтернатнативного файла docker-compose.
docker-compose -f /foo/bar/other-docker-compose.yml up -d
3. Перечитать файл docker-compose:
docker-compose up -d
* на самом деле, команда такая же, как для запуска. Система если определит, что есть изменения, пересоздаст контейнер.
Перечитать и пересобрать контейнеры, если есть инструкция build:
docker-compose up -d —build
4. Остановить контейнеры.
Только остановить контейнеры:
Остановить контейнеры с удаление данных (в volumes):
docker-compose down —volumes
Healthcheck
Данная директива, хоть и является частью сервиса, мы рассмотрим ее в отдельном разделе. Синтаксис:
- test — наш скрипт, который должен вернуть 0, если все хорошо, или 1 — если все плохо.
- interval — как часто запускать проверку.
- timeout — как долго нужно ждать ответа.
- retries — сколько раз тест должен вернуть отрицательный результат, чтобы контейнер перешел в состояние «unhealthy».
1. Проверка работы веб-портала. Рассмотрим пример, когда сайт при правильной работы должен возвращать слово works:
* в данном примере мы запросим у нашего сервера страницу по http и выведем строку, в которой есть слово works. Если такой строки не найдется, команда вернет код 1.
2. Проверка СУБД mysql. Проверку можно выполнить с помощью запроса SELECT 1. В композ-файле это выглядит так:
Читайте также
Другие инструкции, связанные с Docker:
1. Установка Docker на Linux.
2. Создание собственного образа Docker.
3. Настройка локального репозитория для образов Docker и работа с ним.
Установка Docker Compose
Docker применяется для управления отдельными контейнерами (сервисами), из которых состоит приложение. Docker Compose используется для одновременного управления несколькими контейнерами, входящими в состав приложения. Этот инструмент предлагает те же возможности, что и Docker, но позволяет работать с более сложными приложениями.
sudo curl -L "https://github.com/docker/compose/releases/download/1.25.4/docker-compose-$(uname -s)-$(uname -m)" \ sudo chmod +x /usr/local/bin/docker-compose sudo ln -s /usr/local/bin/docker-compose /usr/bin/docker-compose
docker-compose version 1.25.4, build 8d51620a
Файл docker-compose. yml
Набор сервисов, которые нужны для работы приложения, определяется с помощью файла docker-compose.yml
. У нас уже есть директория www
— создадим в ней еще один файл:
. 8080:80
Теперь построчно разберёмся с параметрами:
version
— какая версияdocker-compose.yml
используетсяservices
— контейнеры, которые нужно запуститьapp
— имя сервиса, может быть любым, но осмысленнымbuild
— шаги, описывающие процесс билдингаcontext
— где находитсяDockerfile
для контейнераports
— соответствие портов хоста и контейнера
Теперь проект надо собрать — это похоже на сборку образа в Docker, но здесь идет сборка нескольких образов. Хотя в нашем случае образ всего один:
Проверим, что был создан новый образ:
REPOSITORY TAG IMAGE ID CREATED SIZE
--------------------------------------------------------------------------------------------
www_app latest ce3c26a2cb52 17 seconds ago 410MB
apache-php72 latest eb9a7fb87880 22 hours ago 410MB
ubuntu-share-etc latest ebc1eef0eca3 42 hours ago 64.2MB
php 7.2-apache 4e96f7d06518 2 days ago 410MB
php-cli-script latest 9fff2bf618ad 2 days ago 398MB
tokmakov/apache2_ubuntu latest 18073a80c28b 3 days ago 191MB
php 7.2-cli 555ec78042a1 3 weeks ago 398MB
ubuntu latest 72300a873c2c 4 weeks ago 64.2MB
hello-world latest fce289e99eb9 14 months ago 1.84kB
Теперь запустим эти сервисы, которые создали (хотя у нас всего один сервис):
Creating network "www_default" with the default driver Creating www_app_1 ... done Attaching to www_app_1 app_1 | AH00558: apache2: Could not reliably determine the server's fully qualified domain name, using 172.18.0.2. Set the 'ServerName' directive globally to suppress this message app_1 | AH00558: apache2: Could not reliably determine the server's fully qualified domain name, using 172.18.0.2. Set the 'ServerName' directive globally to suppress this message app_1 | [Sun Mar 22 08:31:46.482140 2020] [mpm_prefork:notice] [pid 1] AH00163: Apache/2.4.38 (Debian) PHP/7.2.29 configured -- resuming normal operations app_1 | [Sun Mar 22 08:31:46.486761 2020] [core:notice] [pid 1] AH00094: Command line: 'apache2 -D FOREGROUND'
Запускаем браузер и открываем http://localhost:8080
:
Остановим работу контейнера с помощью Ctrl+C
и посмотрим на список контейнеров:
docker container ls -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
--------------------------------------------------------------------------------------------------------------------------------
a6e37dee6924 apache-php72 "docker-php-entrypoi…" 2 hours ago Exited (0) 2 hours ago beautiful_turing
................................................................................................................................
8aa1a9458932 php-cli-script "php /script.php 8" 2 days ago Exited (0) 2 days ago optimistic_maxwell
37def446ae84 ubuntu "/bin/bash" 4 days ago Exited (0) 2 days ago apache2_ubuntu
Поиск:
CLI • Docker • Linux • Ubuntu • Виртуализация • Команда • Настройка • Процесс • Установка
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.
Руководство по Docker Compose файлу
Compose файл использует YAML формат и определяет сервисы, сети и тома. По умолчанию Compose файл имеет имя ./docker-compose.yml и располагается в корне проекта.
Определение сервиса contains configuration which will be applied to each container started for that service, much like passing command-line parameters to docker run. Также, network and volume definitions are analogous to docker network create and docker volume create.
As with docker run, options specified in the Dockerfile (e.g., CMD, EXPOSE, VOLUME, ENV) are respected by default — you don’t need to specify them again in docker-compose.yml.
Руководство по конфигурации сервисов
В этом разделе содержится список всех параметров конфигурации, поддерживаемых определением службы.
build
Параметры конфигурации, которые применяются во время сборки.
build можно указать либо как строку, содержащую путь к контексту сборки, либо как объект с путем, указанным в контексте и, возможно, dockerfile и args.
build: ./dir
build:
context: ./dir
dockerfile: Dockerfile-alternate
args:
buildno: 1
If you specify image as well as build, then Compose names the built image with the webapp and optional tag specified in image:
build: ./dir
image: webapp:tag
This will result in an image named webapp and tagged tag, built from ./dir.
Note: In the version 1 file format, build is different in two ways:
- Only the string form (build: .) is allowed — not the object form.
- Using build together with image is not allowed. Attempting to do so results in an error.
context
Either a path to a directory containing a Dockerfile, or a url to a git repository.
When the value supplied is a relative path, it is interpreted as relative to the location of the Compose file. This directory is also the build context that is sent to the Docker daemon.
Compose will build and tag it with a generated name, and use that image thereafter.
dockerfile
Compose will use an alternate file to build with. A build path must also be specified.
build:
context: .
dockerfile: Dockerfile-alternate
-
It appears alongside build, not as a sub-option:
build: . dockerfile: Dockerfile-alternate
-
Using dockerfile together with image is not allowed. Attempting to do so results in an error.
args
Add build arguments, which are environment variables accessible only during the build process.
First, specify the arguments in your Dockerfile:
ARG buildno
ARG password
RUN echo "Build number: $buildno"
RUN script-requiring-password.sh "$password"
Then specify the arguments under the build key. You can pass either a mapping or a list:
build:
context: .
args:
buildno: 1
password: secret
build:
context: .
args:
- buildno=1
- password=secret
You can omit the value when specifying a build argument, in which case its value at build time is the value in the environment where Compose is running.
args:
- buildno
- password
Note: YAML boolean values (true, false, yes, no, on, off) must be enclosed in quotes, so that the parser interprets them as strings.
cap_add, cap_drop
Add or drop container capabilities. See man 7 capabilities for a full list.
cap_add:
- ALL
cap_drop:
- NET_ADMIN
- SYS_ADMIN
command
Override the default command.
command: bundle exec thin -p 3000
The command can also be a list, in a manner similar to dockerfile:
command: [bundle, exec, thin, -p, 3000]
cgroup_parent
Specify an optional parent cgroup for the container.
cgroup_parent: m-executor-abcd
container_name
Specify a custom container name, rather than a generated default name.
container_name: my-web-container
Because Docker container names must be unique, you cannot scale a service beyond 1 container if you have specified a custom name. Attempting to do so results in an error.
devices
List of device mappings. Uses the same format as the —device docker client create option.
devices:
- "/dev/ttyUSB0:/dev/ttyUSB0"
depends_on
Express dependency between services, which has two effects:
version: '2'
services:
web:
build: .
depends_on:
- db
- redis
redis:
image: redis
db:
image: postgres
dns
Custom DNS servers. Can be a single value or a list.
dns: 8.8.8.8
dns:
- 8.8.8.8
- 9.9.9.9
dns_search
Custom DNS search domains. Can be a single value or a list.
dns_search: example.com
dns_search:
- dc1.example.com
- dc2.example.com
tmpfs
Mount a temporary file system inside the container. Can be a single value or a list.
tmpfs: /run
tmpfs:
- /run
- /tmp
entrypoint
Override the default entrypoint.
entrypoint: /code/entrypoint.sh
The entrypoint can also be a list, in a manner similar to dockerfile:
entrypoint:
- php
- -d
- zend_extension=/usr/local/lib/php/extensions/no-debug-non-zts-20100525/xdebug.so
- -d
- memory_limit=-1
- vendor/bin/phpunit
env_file
Add environment variables from a file. Can be a single value or a list.
If you have specified a Compose file with docker-compose -f FILE, paths in env_file are relative to the directory that file is in.
Environment variables specified in environment override these values.
env_file: .env
env_file:
- ./common.env
- ./apps/web.env
- /opt/secrets.env
# Set Rails/Rack environment
RACK_ENV=development
Note: If your service specifies a build option, variables defined in environment files will not be automatically visible during the build. Use the args sub-option of build to define build-time environment variables.
environment
Add environment variables. You can use either an array or a dictionary. Any boolean values; true, false, yes no, need to be enclosed in quotes to ensure they are not converted to True or False by the YML parser.
Environment variables with only a key are resolved to their values on the machine Compose is running on, which can be helpful for secret or host-specific values.
environment:
RACK_ENV: development
SHOW: 'true'
SESSION_SECRET:
environment:
- RACK_ENV=development
- SHOW=true
- SESSION_SECRET
Note: If your service specifies a build option, variables defined in environment will not be automatically visible during the build. Use the args sub-option of build to define build-time environment variables.
expose
Expose ports without publishing them to the host machine — they’ll only be accessible to linked services. Only the internal port can be specified.
expose:
- "3000"
- "8000"
extends
Extend another service, in the current file or another, optionally overriding configuration.
You can use extends on any service together with other configuration keys. The extends value must be a dictionary defined with a required service and an optional file key.
extends:
file: common.yml
service: webapp
The service the name of the service being extended, for example web or database. The file is the location of a Compose configuration file defining that service.
If you omit the file Compose looks for the service configuration in the current file. The file value can be an absolute or relative path. If you specify a relative path, Compose treats it as relative to the location of the current file.
You can extend a service that itself extends another. You can extend indefinitely. Compose does not support circular references and docker-compose returns an error if it encounters one.
external_links
external_links:
- redis_1
- project_db_1:mysql
- project_db_1:postgresql
Note: If you’re using the version 2 file format, the externally-created containers must be connected to at least one of the same networks as the service which is linking to them.
Add hostname mappings. Use the same values as the docker client —add-host parameter.
extra_hosts:
- "somehost:162.242.195.82"
- "otherhost:50.31.209.229"
An entry with the ip address and hostname will be created in /etc/hosts inside containers for this service, e.g:
162.242.195.82 somehost
50.31.209.229 otherhost
image
Specify the image to start the container from. Can either be a repository/tag or a partial image ID.
image: redis
image: ubuntu:14.04
image: tutum/influxdb
image: example-registry.com:4000/postgresql
image: a4bc65fd
If the image does not exist, Compose attempts to pull it, unless you have also specified build, in which case it builds it using the specified options and tags it with the specified tag.
Note: In the version 1 file format, using build together with image is not allowed. Attempting to do so results in an error.
labels
Add metadata to containers using Docker labels. You can use either an array or a dictionary.
It’s recommended that you use reverse-DNS notation to prevent your labels from conflicting with those used by other software.
labels:
com.example.description: "Accounting webapp"
com.example.department: "Finance"
com.example.label-with-empty-value: ""
labels:
- "com.example.description=Accounting webapp"
- "com.example.department=Finance"
- "com.example.label-with-empty-value"
links
Link to containers in another service. Either specify both the service name and a link alias (SERVICE:ALIAS), or just the service name.
web:
links:
- db
- db:database
- redis
Containers for the linked service will be reachable at a hostname identical to the alias, or the service name if no alias was specified.
Links also express dependency between services in the same way as depends_on, so they determine the order of service startup.
logging
Logging configuration for the service.
logging:
driver: syslog
options:
syslog-address: "tcp://192.168.0.42:123"
The driver name specifies a logging driver for the service’s containers, as with the —log-driver option for docker run (documented here).
The default value is json-file.
driver: "json-file"
driver: "syslog"
driver: "none"
Note: Only the json-file driver makes the logs available directly from docker-compose up and docker-compose logs. Using any other driver will not print any logs.
Specify logging options for the logging driver with the options key, as with the —log-opt option for docker run.
Logging options are key-value pairs. An example of syslog options:
driver: "syslog"
options:
syslog-address: "tcp://192.168.0.42:123"
log_driver
Specify a log driver. The default is json-file.
log_opt
Specify logging options as key-value pairs. An example of syslog options:
log_opt:
syslog-address: "tcp://192.168.0.42:123"
net
net: "bridge"
net: "host"
net: "none"
net: "container:[service name or container name/id]"
network_mode
network_mode: "bridge"
network_mode: "host"
network_mode: "none"
network_mode: "service:[service name]"
network_mode: "container:[container name/id]"
networks
services:
some-service:
networks:
- some-network
- other-network
aliases
Aliases (alternative hostnames) for this service on the network. Other containers on the same network can use either the service name or this alias to connect to one of the service’s containers.
Since aliases is network-scoped, the same service can have different aliases on different networks.
The general format is shown here.
services:
some-service:
networks:
some-network:
aliases:
- alias1
- alias3
other-network:
aliases:
- alias2
In the example below, three services are provided (web, worker, and db), along with two networks (new and legacy). The db service is reachable at the hostname db or database on the new network, and at db or mysql on the legacy network.
version: '2'
services:
web:
build: ./web
networks:
- new
worker:
build: ./worker
networks:
- legacy
db:
image: mysql
networks:
new:
aliases:
- database
legacy:
aliases:
- mysql
networks:
new:
legacy:
ipv4_address, ipv6_address
Specify a static IP address for containers for this service when joining the network.
version: '2'
services:
app:
image: busybox
command: ifconfig
networks:
app_net:
ipv4_address: 172.16.238.10
ipv6_address: 2001:3984:3989::10
networks:
app_net:
driver: bridge
driver_opts:
com.docker.network.enable_ipv6: "true"
ipam:
driver: default
config:
- subnet: 172.16.238.0/24
gateway: 172.16.238.1
- subnet: 2001:3984:3989::/64
gateway: 2001:3984:3989::1
pid
Sets the PID mode to the host PID mode. This turns on sharing between container and the host operating system the PID address space. Containers launched with this flag will be able to access and manipulate other containers in the bare-metal machine’s namespace and vise-versa.
ports
Expose ports. Either specify both ports (HOST:CONTAINER), or just the container port (a random host port will be chosen).
Note: When mapping ports in the HOST:CONTAINER format, you may experience erroneous results when using a container port lower than 60, because YAML will parse numbers in the format xx:yy as sexagesimal (base 60). For this reason, we recommend always explicitly specifying your port mappings as strings.
ports:
- "3000"
- "3000-3005"
- "8000:8000"
- "9090-9091:8080-8081"
- "49100:22"
- "127.0.0.1:8001:8001"
- "127.0.0.1:5000-5010:5000-5010"
security_opt
Override the default labeling scheme for each container.
security_opt:
- label:user:USER
- label:role:ROLE
stop_signal
Sets an alternative signal to stop the container. By default stop uses SIGTERM. Setting an alternative signal using stop_signal will cause stop to send that signal instead.
ulimits
Override the default ulimits for a container. You can either specify a single limit as an integer or soft/hard limits as a mapping.
ulimits:
nproc: 65535
nofile:
soft: 20000
hard: 40000
volumes, volume_driver
Mount paths or named volumes, optionally specifying a path on the host machine (HOST:CONTAINER), or an access mode (HOST:CONTAINER:ro). For version 2 files, named volumes need to be specified with the top-level volumes key. When using version 1, the Docker Engine will create the named volume automatically if it doesn’t exist.
volumes:
# Just specify a path and let the Engine create a volume
- /var/lib/mysql
# Specify an absolute path mapping
- /opt/data:/var/lib/mysql
# Path on the host, relative to the Compose file
- ./cache:/tmp/cache
# User-relative path
- ~/configs:/etc/configs/:ro
# Named volume
- datavolume:/var/lib/mysql
If you do not use a host path, you may specify a volume_driver.
Note that for version 2 files, this driver will not apply to named volumes (you should use the driver option when declaring the volume instead). For version 1, both named volumes and container volumes will use the specified driver.
Note: No path expansion will be done if you have also specified a volume_driver.
volumes_from
Mount all of the volumes from another service or container, optionally specifying read-only access (ro) or read-write (rw). If no access level is specified, then read-write will be used.
volumes_from:
- service_name
- service_name:ro
- container:container_name
- container:container_name:rw
- service_name - service_name:ro - container_name - container_name:rw
cpu_shares, cpu_quota, cpuset, domainname, hostname, ipc, mac_address, mem_limit, memswap_limit, privileged, read_only, restart, shm_size, stdin_open, tty, user, working_dir
Each of these is a single value, analogous to its docker run counterpart.
cpu_shares: 73
cpu_quota: 50000
cpuset: 0,1
user: postgresql
working_dir: /code
domainname: foo.com
hostname: foo
ipc: host
mac_address: 02:42:ac:11:65:43
mem_limit: 1000000000
memswap_limit: 2000000000
privileged: true
restart: always
read_only: true
shm_size: 64M
stdin_open: true
tty: true
Инструкция VOLUME в Dockerfile
Эта инструкция устарела и использовать ее не рекомендуется. Но давайте все таки познакомимся с ней поближе для общего понимания. Создадим в домашней директории каталог test
и внутри него — файл Dockerfile
:
FROM ubuntu:latest VOLUME /etc
Соберем образ из этого Dockerfile
:
Запустим новый контейнер:
Теперь посмотрим, какие тома существуют:
docker volume ls
DRIVER VOLUME NAME
local 8bda345c875c99d61f9646a9b0922934a7eaab83366c04159f6023654237f090
local data-sql
local data-www
Где физически расположены тома, мы уже знаем. Так что посмотрим содержимое нового тома:
sudo ls /var/lib/docker/volumes/8bda345c875c99d61f9646a9b0922934a7eaab83366c04159f6023654237f090/_data/
adduser.conf debconf.conf fstab hosts ld.so.conf lsb-release opt profile.d rc5.d security subuid
alternatives debian_version gai.conf init.d ld.so.conf.d machine-id os-release rc0.d rc6.d selinux sysctl.conf
apt default group issue legal mke2fs.conf pam.conf rc1.d rcS.d shadow sysctl.d
bash.bashrc deluser.conf gshadow issue.net libaudit.conf mtab pam.d rc2.d resolv.conf shells systemd
bindresvport.blacklist dpkg host.conf kernel login.defs networks passwd rc3.d rmt skel terminfo
cron.daily environment hostname ld.so.cache logrotate.d nsswitch.conf profile rc4.d securetty subgid update-motd.d
Это содержимое каталога /etc
контейнера. Так что мы можем, используя инструкцию VOLUME
, сохранять на основной системе любые директории контейнера. И при удалении контейнера тома будут по-прежнему существовать. Впрочем, можно вместе с удалением контейнера удалить и связанный с ним том:
Возможные ошибки
Network <net-name>_default Error
При попытке запустить compose получаем ошибку:
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
Решение: быстрее всего выполнить чистку docker от неиспользуемых сетей. Для этого выполняем команду:
docker network prune
Сервисы
В данном разделе рассмотрим примеры настроек сервисов (контейнеров). Синтаксис:
services:
<имя сервиса>:
<настройки сервиса>
1. Создание контейнера из готового образа. Образ указывается с помощью директивы image:
* в данном примере будет взят образ nginx для поднятия контейнера.
2. Сборка контейнера из Dockerfile. Для этого используем опцию build:
build:
context: ./web-server/
args:
buildno: 22042001
- build — указание на необходимость сборки из Dockerfile. Пример создания последнего читайте в инструкции Создание собственного образа Docker.
- context — путь, где нужно искать Dockerfile относительно места, где находится docker-compose файл.
- buildno — номер для сборки.
3. Проброс папок (volumes). Настраивается с помощью опции volumes:
volumes:
— /data/mysql:/var/lib/mysql
* в нашем примере мы смонтируем локальный каталог /data/mysql на хосте внутрь контейнера в качестве каталога /var/lib/mysql.
Также мы можем смонтировать папку только на чтение, например:
volumes:
— /:/rootfs:ro
4. Работа с портами. Рассмотрим несколько вариантов работы с портами.
а) Ports (внешняя публикация). С помощью данной опции мы можем указывать, на каких портах должен слушать контейнер и на какие порты должны пробрасываться запросы:
ports:
— 8080:80
* в данном примере наш контейнер будет слушать запросы на порту 8080 и передавать их внутрь контейнера на порт 80.
Или можно прописать так:
ports:
— 80
* в этом примере будет настроен проброс на порт 80. Внешний порт будет выбран docker автоматически.
б) Expose (внутрення публикация). Данная опция задает порт, на котором должно слушать приложение внутри контейнера, но проброса с внешнего адреса не будет — отправить запрос по сети на данный порт можно с другого контейнера:
expose:
— 7000
5. Переменные окружения. В нашей универсальной заготовке мы уже использовали одну системную переменную:
environment:
TZ: «Europe/Moscow»
Чтобы передать несколько переменных, просто их перечисляем:
environment:
TZ: «Europe/Moscow»
MYSQL_ROOT_PASSWORD=password
Для каждого приложения есть свой набор системных переменных, которые оно понимает и интерпретирует. Например, MYSQL_ROOT_PASSWORD поймет СУБД и установит значение в качестве пароля для пользователя root.
Также системные переменные можно передать не в сценарии docker-compose, а в файле .env — просто создадим этот файл в одной директории с файлом docker-compose.yml:
6. Зависимости для контейнеров. Мы можем указать с помощью опции depends_on, от какого контейнера зависит сервис:
depends_on:
— db
* в конкретном примере, контейнер не запустится, пока не поднимется db.
7. Переопределить команду. С помощью директивы command мы можем переопределить команду для запуска, например:
* в данном примере мы запустим redis-server с альтернативным конфигурационным файлом.
Или можно написать так:
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»
8. Метки. С помощью опции labels мы можем указывать дополнительную информацию для ориентирования или фильтров при поиске контейнеров:
* данные могут быть произвольные. Обратите внимание, что в качестве значений мы указали переменные, которые можно просто передать из системного окружения.
10. Домашняя директория. Определяет положение по умолчанию, откуда будут выполняться команды.
Variable substitution
Your configuration options can contain environment variables. Compose uses the variable values from the shell environment in which docker-compose is run. For example, suppose the shell contains EXTERNAL_PORT=8000 and you supply this configuration:
web:
build: .
ports:
- "${EXTERNAL_PORT}:5000"
When you run docker-compose up with this configuration, Compose looks for the EXTERNAL_PORT environment variable in the shell and substitutes its value in. In this example, Compose resolves the port mapping to «8000:5000» before creating the web container.
If an environment variable is not set, Compose substitutes with an empty string. In the example above, if EXTERNAL_PORT is not set, the value for the port mapping is :5000 (which is of course an invalid port mapping, and will result in an error when attempting to create the container).
You can use a $$ (double-dollar sign) when your configuration needs a literal dollar sign. This also prevents Compose from interpolating a value, so a $$ allows you to refer to environment variables that you don’t want processed by Compose.
web:
build: .
command: "$$VAR_NOT_INTERPOLATED_BY_COMPOSE"
If you forget and use a single dollar sign ($), Compose interprets the value as an environment variable and will warn you:
The VAR_NOT_INTERPOLATED_BY_COMPOSE is not set. Substituting an empty string.
Порты контейнера
Docker позволяет получить доступ к какому-то из портов контейнера, пробросив его наружу — в основную операционную систему. По умолчанию, мы не можем достучаться к какому-либо порту контейнера. Однако, интсрукция EXPOSE
в Dockerfile
позволяет объявить, к какому из портов можно обратиться из основной системы.
Создадим в домашней директории каталог www
и внутри него — файлы Dockerfile
и index.php
:
# Образ с DockerHub, включает Apache и PHP FROM php:7.2-apache # Копируем все файлы проекта в контейнер COPY . /var/www/html # Сообщаем, какие порты контейнера слушать EXPOSE 80
Hello from Apache
Создадим новый образ из Dockerfile
:
docker build . --tag apache-php72
Запустим контейнер и укажем, что порт 80 контейнера будет связан с портом 8080 хоста:
docker run -p 8080:80 apache-php72
AH00558: apache2: Could not reliably determine the server's fully qualified domain name, using 172.17.0.4. Set the 'ServerName' directive globally to suppress this message
AH00558: apache2: Could not reliably determine the server's fully qualified domain name, using 172.17.0.4. Set the 'ServerName' directive globally to suppress this message
[Sat Mar 21 10:19:35.224973 2020] [mpm_prefork:notice] [pid 1] AH00163: Apache/2.4.38 (Debian) PHP/7.2.29 configured -- resuming normal operations
[Sat Mar 21 10:19:35.233317 2020] [core:notice] [pid 1] AH00094: Command line: 'apache2 -D FOREGROUND'
Запускаем браузер и открываем http://localhost:8080
:
Базовый шаблон
В первую очередь, предлагаю заготовку для docker-compose файла, на основе которой можно начинать писать свой сценарий для docker.
Создаем файл для работы с контейнерами:
<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.
Типы томов Docker
Есть два основных способа обмена данными с контейнером, которые часто называют томами:
- Перенаправление папки или файла с хоста в контейнер, называется
bind mount
- Создание специального объекта, который имеет больше возможностей управления данными
volume
- В случае
bind mount
файлindex.html
, внутри контейнера, будет удален. Это произойдет даже если папка хоста пустая - В случае
volume
при первом использовании файлindex.html
будет скопирован. При последующих удален
Создание Volumes через docker run
Для монтирования данных используются следующие параметры:
-v
или--volume
--mount
Их различие в том, что bind mount
более явно заставляет указывать источник и цель монтирования папки. Вы можете использовать эти параметры совместно, отдельно, повторяя несколько раз, ограничений нет.
Папки и файлы
Для примера, у меня есть следующая папка на хосте:
/home/alex/docker_data
В случае параметра -v
указывается два пути откуда:куда
. В случае --mount
это именованные параметры разделенные запятыми, пример работы обоих:
-v /home/alex/docker_data:/usr/share/nginx/html
--mount type=bind,source=/home/alex/docker_data,destination=/usr/share/nginx/html
В mount
мы используем следующие параметры:
type
со значениемbind
говорит, что мы монтируем папку или файлsource
источник, папка или файл, который мы хотим подключить к контейнеруdestination
папка или файл внутри контейнера
В обоих случаях мы можем монтировать данный доступные только для чтения read-only
добавив ro
в конце:
-v /home/alex/docker_data:/usr/share/nginx/html:ro
--mount type=bind,source=/home/alex/docker_data,destination=/usr/share/nginx/html,ro
Так выглядит запуск контейнера с проброшенной папкой:
docker run -d --name nginx_vol1 -v /home/alex/docker_data:/usr/share/nginx/html:ro nginx
docker run -d --name nginx_vol2 --mount type=bind,source=/home/alex/docker_data,destination=/usr/share/nginx/html,ro nginx
Можно задать следующие опции:
rprivate
private
rshared
shared
rslave
slave
ro
режим только для чтенияz
папка на хосте может быть использована несколькими контейнерамиZ
папка используется только одним контейнером
Первые шесть параметров позволяют управлять тем, как будут влиять изменения в одной точке монтирования тома на другие точки монтирования. По умолчанию используется rprivate
, что означает — никак.
Подключение volume
При монтировании тома нужно учитывать следующие моменты:
- Название тома указывается без слешей
- Если тома с этим названием нет, он будет создан
- В случае с
mount
, в параметреtype
, указываетсяvolume
При использовании docker run
использование томов будет выглядеть так:
docker run -d --name nginx_vol1 -v docker_volume:/usr/share/nginx/html nginx
docker run -d --name nginx_vol2 --mount type=volume,source=docker_volume,destination=/usr/share/nginx/html nginx
Так же как и с папками мы можем добавить :ro
или ,ro
в конец значения, что бы дать права только на чтение директорий.
В предыдущем примере один том был подключен к двум контейнерам. Их совместную работу можно проверить создав файл в одном контейнере, а вывести через другой:
# создаем файл в одном контейнере
docker exec nginx_vol1 touch /usr/share/nginx/html/file1
# проверяем файл через другой контейнер
docker exec nginx_vol2 ls /usr/share/nginx/html
Создание Volumes через Dockerfile
При создании образа через Dockerfile у вас есть возможность создать том, но не использовать существующий. Смонтировать папку, через Dockerfile, нельзя.
Создание тома будет иметь ряд ограничений:
- Вы не сможете указать имя тома или выбрать существующий. Имя будет сгенерировано автоматически
- В любом случае том будет создан во время запуска контейнера т.е. так же как и в случае использования
-v
- Каждое создание контейнера будет создавать новый том
Для создания тома есть инструкция VOLUME
, пример синтаксиса:
FROM nginx
# указываем точку монтирования внутри контейнера
VOLUME /somedata1
Примерный результат где запускаются 2 контейнера с одного образа:
Аналогичный результат можно получить используя одну из следующих команд:
docker run -v /somedata1 nginx
docker run -v $(docker volume create):/somedata1 nginx
Если вы используете инструкцию VOLUME
и параметр -v
указывающий на одну и ту же директорию, то -v
возьмет верх.
Создание Volumes через docker-compose
Docker-compose
позволяет запускать несколько контейнеров используя один файл инструкций. Синтаксис монтирования томов может быть ограниченным и расширенным так же как -v
и --mount
.
Для монтирования тома, кроме инструкции в самом контейнере, нужно указать дополнительную инструкцию volumes
в верхнем уровне. Для папки этого делать не нужно:
version: "3.8"
services:
web:
image: nginx:alpine
volumes:
# том
- somevol:/app
# папка
- /home/alex:/app2
# для тома
volumes:
somevol:
Том somevol
может использоваться совместно в нескольких контейнерах.
Если нам нужно дать права на том или папку, то мы просто добавляем ro
или rw
в конец пути:
...
volumes:
# том
- somevol:/app:ro
# папка
- /home/alex:/app2:rw
...
Для монтирования так же есть расширенный синтаксис, похожий на команду mount
в docker. Следующий пример аналогичен предыдущем по эффекту:
version: "3.8"
services:
web:
image: nginx:alpine
volumes:
# том
- type: volume
source: somevol
target: /app1
# папка
- type: bind
source: /home/alex
target: /app2
volumes:
somevol:
Есть еще инструкции, которые вы можете использовать. Ниже только их часть, но они используются редко:
volumes:
- type: volume
source: somevol
target: /app1
# папка только для чтения
read_only: true
# не будет копировать файлы в том, которые уже находятся в контейнере
volume:
nocopy: true
# папка
- type: bind
source: /home/alex
target: /app2
# папка только для чтения
read_only: true
# создаст папку на хосте если ее нет
create_host_path: true
Мы можем использовать один и тот же том в нескольких контейнерах (сервисах). Кроме этого есть инструкция volumes_from
, которая использует тома с указанного контейнера, ниже оба примера:
version: "3.8"
services:
container1:
image: nginx:alpine
volumes:
- somevol:/app1
- /home/alex:/app2
container2:
image: nginx:alpine
volumes:
# тот же том, но в другом контейнере
- somevol:/app2
container3:
image: nginx:alpine
# берем тома из сервиса container1
# с доступностью только на чтение
volumes_from:
- container1:ro
volumes:
somevol:
Использование внешних томов
Если вам нужно использовать том, который был создан не в текущем файле docker-compose.yml
, то вы можете его указать через параметр external
, автоматический такой том не создается:
...
volumes:
somevol:
external: true
Создание тома в другой директории
Через docker-compose.yml
мы можем указывать драйвера и опции. Например, создадим тома в другой директории по аналогии с тем, что делали выше:
...
volumes:
my_test_volume:
driver: local
driver_opts:
o: bind
type: none
device: /home/alex/compose_vol1
Монтирование через Tmpfs
Еще одним способом монтирования томов является tmpfs
. Данные этого тома хранятся в оперативной памяти. При остановке контейнера, в отличие от других томов, данные будут удалены. Эти данные просто не выгружаются из оперативной памяти. Такой тип тома вы можете создать только на одном контейнере и только в Linux.
Такие типы хранилищ редко используются. Их можно использовать для хранения чувствительных данных (для безопасности) или что бы ускорить работу какого-то приложения, но оба варианта, обычно, реализовываются на стороне приложения. Есть два способа создания tmpfs
.
docker run \
--tmpfs /app \
nginx:latest
# или
docker run -d \
--mount type=tmpfs,destination=/app,tmpfs-size=400,tmpfs-mode=1777 \
nginx:latest
При использовании параметра --tmpfs
вы можете указать только директорию, которую планируете использовать.
При использовании mount
у вас появляются не обязательные параметры:
tmpfs-size
размер в байтах, по умолчанию не ограниченtmpfs-mode
права на файлы, по умолчанию 1777. Можно не указывать специальные разрешения (т.е. 700, например).
Второй способ через docker-compose.yml
:
volumes:
foo:
driver: local
driver_opts:
type: "tmpfs"
o: "o=size=100m,uid=1000"
device: "tmpfs"
Просмотр привязанных томов
Вы можете объявлять тома внутри смонтированных папок и наоборот. Это может создавать путаницу, но это требуется в определенных ситуациях. Например некоторые фреймворки используют следующую структуру хранение модулей и приложений:
docker inspect название_контейнера --format "'{{json .Mounts}}'"
sudo docker inspect название_контейнера | grep Mountpoint | awk '{ print $2 }'
Привязка томов из другого контейнера
С помощью параметра --volumes-from
мы можем скопировать тома у запущенного или остановившегося тома, в значении мы указываем контейнер:
# контейнер 1
docker run -v $(pwd)/app:/usr/src/app \
-v node_modules:/usr/src/app/node_modules \
--name node1 \
node
# контейнер 2
docker run --volumes-from node1 --name node2 node
Создание и удаление Volume
volume
это отдельны объект у docker есть команды, с помощью которых можно им управлять:
Выведет список томов:
docker volume ls
Покажет подробную информацию о томе, даже его расположение на хосте:
docker volume inspect
Создание нового тома:
docker volume create
Удалит все тома, которые не используются контейнерами:
docker volume prune
Удалит один том:
docker volume rm
Network configuration reference
The top-level networks key lets you specify networks to be created. For a full explanation of Compose’s use of Docker networking features, see the Networking guide.
driver
Specify which driver should be used for this network.
The default driver depends on how the Docker Engine you’re using is configured, but in most instances it will be bridge on a single host and overlay on a Swarm.
The Docker Engine will return an error if the driver is not available.
driver_opts
driver_opts:
foo: "bar"
baz: 1
ipam
Specify custom IPAM config. This is an object with several properties, each of which is optional:
- driver: Custom IPAM driver, instead of the default.
- config: A list with zero or more config blocks, each containing any of the following keys:
- subnet: Subnet in CIDR format that represents a network segment
- ip_range: Range of IPs from which to allocate container IPs
- gateway: IPv4 or IPv6 gateway for the master subnet
- aux_addresses: Auxiliary IPv4 or IPv6 addresses used by Network driver, as a mapping from hostname to IP
A full example:
ipam:
driver: default
config:
- subnet: 172.28.0.0/16
ip_range: 172.28.5.0/24
gateway: 172.28.5.254
aux_addresses:
host1: 172.28.1.5
host2: 172.28.1.6
host3: 172.28.1.7
external
If set to true, specifies that this network has been created outside of Compose. docker-compose up will not attempt to create it, and will raise an error if it doesn’t exist.
external cannot be used in conjunction with other network configuration keys (driver, driver_opts, ipam).
version: '2'
services:
proxy:
build: ./proxy
networks:
- outside
- default
app:
build: ./app
networks:
- default
networks:
outside:
external: true
You can also specify the name of the network separately from the name used to refer to it within the Compose file:
networks:
outside:
external:
name: actual-name-of-network
Volume configuration reference
driver
Specify which volume driver should be used for this volume. Defaults to local. The Docker Engine will return an error if the driver is not available.
driver_opts
driver_opts:
foo: "bar"
baz: 1
external
If set to true, specifies that this volume has been created outside of Compose. docker-compose up will not attempt to create it, and will raise an error if it doesn’t exist.
external cannot be used in conjunction with other volume configuration keys (driver, driver_opts).
version: '2'
services:
db:
image: postgres
volumes:
- data:/var/lib/postgresql/data
volumes:
data:
external: true
You can also specify the name of the volume separately from the name used to refer to it within the Compose file:
volumes:
data:
external:
name: actual-name-of-volume