
Привет, Хабр! Меня зовут Александр, Системный администратор в компании БАРС Груп Сегодня хочу поделиться своим опытом использования возможностей Docker Compose, которые значительно упростили мне работу. Эти изменения касаются автоматического обновления контейнеров, работы с профилями, использования GPU, а также улучшенного управления сборкой и секретами. На практике заметил, что эти фичи мало используются, и надеюсь, что после прочтения статьи, вы будете чаще использовать эти фичи в своей повседневной работе. Давайте разбираться!
Watch: Кодишь — видишь
Если вы когда-либо работали с Docker Compose, то наверняка знаете, как неудобно каждый раз вручную перестраивать контейнеры после внесения изменений в код. В Docker Compose имеется фича watch, которая решает эту проблему.
Compose может автоматически отслеживать изменения в ваших файлах и мгновенно обновлять работающие контейнеры. Это позволяет сократить время на тестирование новых изменений.
Как настроить? Пробуем!
Пример для Nginx:
services:
web:
image: nginx:alpine
volumes:
- ./html:/usr/share/nginx/html:ro
ports:
- "8080:80"
labels:
com.docker.compose.watch: "true"
Создайте локальную директорию html с файлом index.html для тестирования.
Например, в html/index.html оставьте следующий код:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Docker Watch Test</title>
</head>
<body>
<h1>Привет, Docker Compose Watch!</h1>
</body>
</html>
Запустите проект:
docker compose up
И в отдельной вкладке терминала активируйте watch:
docker compose watch
Теперь, если вы внесёте изменения в файл html/index.html, обновления автоматически применятся. Например, измените текст в теге <h1> и просто обновите браузер, чтобы увидеть результат.
Это особенно полезно в процессе локальной разработки, когда вам нужно быстро тестировать изменения. Удобно? Берём на заметку.
Профили: Настраивайте окружения под свои нужды
Вторая полезная фича — поддержка профилей. Теперь в одном файле docker-compose.yml можно определить разные конфигурации для разных окружений: разработки, тестирования, продакшна.
Пример:
services:
web:
image: nginx:alpine
profiles:
- production
debug:
image: busybox
command: sleep 1000
profiles:
- development
Чтобы запустить Compose с профилем, используйте флаг --profile:
docker compose --profile development up
docker compose --profile production up
Эта функция позволяет легко переключаться между различными конфигурациями без необходимости изменять файл.
GPU Access: Для тех, кто любит мощность
Поддержка GPU стала необходимостью для проектов, связанных с машинным обучением или рендерингом. Теперь Docker Compose позволяет легко указывать использование GPU в контейнерах. Для проверки этого примера потребуется настроить окружение для работы docker c nvidia-tools следуя официальной документации
Пример:
services:
test:
image: nvidia/cuda:12.3.1-base-ubuntu20.04
command: nvidia-smi
deploy:
resources:
reservations:
devices:
- driver: nvidia
count: 1
capabilities: [gpu]
Улучшения сборки: Быстрее, легче, лучше
Docker Compose теперь поддерживает более гибкие настройки процесса сборки. Среди новых возможностей:
Кэширование сборки. Теперь можно ускорить сборку, сохраняя промежуточные слои.
Параллельная сборка. Docker Compose теперь умеет собирать образы одновременно, что ускоряет процесс в больших проектах.
Пример:
Предположим, у вас есть проект с большим количеством Docker-образов. Один из них — приложение app, а другой — база данных db. Вы хотите оптимизировать сборку и использовать кэширование для ускорения процесса.
Помните, это только общий пример, и вам нужно будет адаптировать его к своему проекту. Файл docker-compose.yml будет выглядеть так:
services:
app:
build:
context: ./app
dockerfile: Dockerfile
target: production
cache_from:
- app:cache
db:
build:
context: ./db
dockerfile: Dockerfile
cache_from:
- db:cache
Контекст и таргет: Параметр context указывает путь к директории с Dockerfile, а target позволяет собирать только определённый этап из многоэтапного Dockerfile (например, production).
Кэширование: Флаг cache_from позволяет указывать образы, которые можно использовать для ускорения сборки. Например, ранее сохранённый образ app:cache может помочь избежать повторной сборки неизменённых слоёв.
Как это работает?
Запускаем первую сборку:
docker compose build
Если никаких изменений в файлах нет, процесс сборки будет использовать кэш для каждого этапа.
При изменении кода только в одном сервисе (например, app) Compose пересоберёт только его, оставив db нетронутым. Это значительно ускоряет процесс.
Параллельная сборка активируется автоматически, если используется несколько сервисов. Например, app и db будут собираться одновременно.
Преимущество:
Вы экономите время на сборке больших проектов.
Меньше ресурсов тратится на перестройку неизменённых частей приложения.
Управление секретами: Надежно и безопасно
Docker Compose улучшил поддержку работы с секретами, что делает хранение конфиденциальных данных более безопасным. Теперь вы можете определять секреты в файле Compose и использовать их в контейнерах.
Пример:
secrets:
db_password:
file: ./secrets/db_password.txt
services:
db:
image: postgres
secrets:
- db_password
Доступ к секретам внутри контейнера можно получить через переменные окружения или специальные файлы.
Чем новая версия лучше старой?
Если вы ещё используете старую версию Docker Compose (выполненную как Python-скрипт), то пора уже обновляться!
Вот почему:
Больше возможностей. Новые фичи, такие как watch, profiles и поддержка GPU, доступны только в актуальных версиях.
Производительность. Docker Compose V2 написан на Go, что делает его значительно быстрее и стабильнее.
Совместимость. Новая версия тесно интегрирована с Docker CLI, что упрощает использование.
Да, переход на новую версию может показаться пугающим, но, поверьте, результат того стоит. Разве вам не хочется, чтобы ваши контейнеры обновлялись автоматически, а сборка шла в разы быстрее?
Вывод
Эти обновления делают Docker Compose ещё более мощным инструментом для работы с контейнеризированными приложениями. Вот что особенно радует:
watch — значительно ускоряет локальную разработку.
profiles — упрощает управление конфигурациями для разных сред.
GPU support — расширяет возможности для вычислительных задач.
Улучшения в сборке — ускоряют разработку и CI/CD.
Секреты — обеспечивают безопасность.
Старый Docker Compose — это как телефон с кнопками: надёжный, проверенный, но уже далёкий от современных реалий. Вы можете им пользоваться, но разве не хочется смартфон, который сам обновляет приложения, работает быстрее и предлагает больше функций? Docker Compose V2 — это тот самый смартфон, который преобразит вашу разработку или DevOps-процесс. Обновляйтесь, и пусть ваши контейнеры работают, как часы!
Комментарии (21)
baldr
03.02.2025 16:57новых возможностей Docker Compose
Статья про Docker Compose v2, который был релизнут в 2020 году. В принципе, всё правильно описано, но уже 5 лет прошло.
Кэширование и таргет - скорее фичи Buildkit, который сейчас тоже по-умолчанию используется, а раньше надо было переменной окружения включать.
gigimon
03.02.2025 16:57Какие ужасные примеры, в первом у вас и так все обновится, ведь nginx и так читать будет из волюма. С профилями тоже, пишут про разные настройки для дебага/продакшена, а по факту вы совсем разные сервисы запускаете.
BloodyEagle
03.02.2025 16:57Тоже не понял примера с watch. Оно и без него будет работать прекрасно.
Или это просто статья ради статьи?
pingo
03.02.2025 16:57не, это не будет работать с директивой :ro
я как-то правил конфиг и рестартовал nginx через docker exec web ash и офигивал от отсутствия изменений ))
kozlyuk
03.02.2025 16:57Вы, случайно, не прокидывали только сам файл конфига, а не директорию, где он лежит? Некоторые редакторы при сохранении файла не пишут в него же, а создают временный невидимый, а потом перемещают на место прежнего. При этом меняется inode, а так как проброс делается по inode, а не по пути, то в контейнере изменения действительно не видны.
Tony-Sol
03.02.2025 16:57ro работает внутри фс контейнера, поэтому так не получится, а если изменить файл с хостовой системы, то должен увидеть изменения
arkhiiipov Автор
03.02.2025 16:57Пример с nginx, показывает что так можно и нужно делать. Будь если это приложение Node.js мы хотим, чтобы код автоматически обновлялся без перезапуска контейнера вручную при этом приложение не умеет hot-reload - процесс не увидит изменения. watch ускоряет локальную разработку, убирая ручные перезапуски
kozlyuk
03.02.2025 16:57Пример с Nginx просто не работает (
docker compose version
→ 2.27.0):docker compose watch none of the selected services is configured for watch, consider setting an 'develop' section
При этом F5 в браузере успешно показывает изменения в файлах в проброшенной директории. Судя
docker compose watch --help
, она следит за build context, а не за произвольными проброшенными точками. И если наше приложение не поддерживает hot reload, надо конфигурировать, как именноdocker compose watch
оповестит его, что файлы изменились. И почему черезlabels
, а не штатными средствами (https://docs.docker.com/reference/compose-file/develop/)?arkhiiipov Автор
03.02.2025 16:57Для тестовых целей этого будет достаточно, и да, watch следит за build context. Разные приложения, разные сборки под ваше может потребоваться более тонкая настройка с применением дополнительных спецификаций path и action и.т.д
savostin
03.02.2025 16:57Ждем свежую статью по v3!
baldr
03.02.2025 16:57Ждем свежую статью по v3!
На данный момент последняя версия Docker Compose:
v2.32.4
.Вероятно, вы имели в виду docker compose file v3 - формат файла третьей версии. Но статья не об этом совсем, а о бывшем приложении docker-compose, который стал плагином для Docker (и это и есть v2). Версии 3 пока нет и, возможно, даже не особо планируется.
lioncub
03.02.2025 16:57А ещё сам Dockerfile можно описывать прямо в compose без использования файла (dockerfile_inline).
И было дописать, что кэш можно использовать из image. А где ещё cache_to? И обратное no_cache?
Также подсовывать свой hosts (extra_hosts).
Также можно определить stage для multi-stage Dockerfile (target).
Это так на вскидку.... Полезнее было бы расширить статью.
pingo
Это хорошо, а как в разных секциях сервисов использовать разные файлы окружения, помимо .env? У меня так и не получилось
BioHazzardt
Оно?
pingo
это не работает, у меня не получилось, работает только .env из текущей папки
BioHazzardt
попробуйте убрать .env из папки, либо в другое место переместите. Может он подгружается на уровне приложения (докер считывает файл и передает его просто как переменные окружения, а не как .env-файл)
З.Ы. Есть еще второй вариант - прокинуть .env через volumes
Pinkbyte
УМВР, причем как с .env (глобально для всех контейнеров), так и с переопределенными для конкретных контейнеров env_file(дополнительные опции вдобавок к глобальным из .env)
[root@nms librenms]# docker -v
Docker version 26.1.4, build 5650f9b
Собственно compose-файл - слегка переделанный из репозитария https://github.com/librenms/docker