Как я говорил ранее контейнеры как правило живут не долго, причин на это немало, начиная от простого обновления образа контейнера заканчивая простой выкладкой нового приложения. И если каждый раз пересоздавать контейнер вручную, то придётся писать, как минимум три команды для каждого контейнера (стоп, удалить, старт). Помимо этого, нужно еще вспомнить какой образ используется. Ну а если у вас проект, который состоит из нескольких контейнеров одновременно то всё становится еще сложнее.
Еще одно преимущество использования Docker Compose это быстрая изоляция одних контейнеров от других и связь контейнеров по сети. У меня уже есть статьи про сети и про DNS псевдонимы. Используя Docker Compose вы можете автоматически объединить несколько контейнеров в одну общую сеть и обращаться внутри сети по dns именам.
Также используя Docker Compose можно управлять и хранилищем для контейнеров.
И всё это можно получить просто, описав весь конфиг в одном файле. В качестве конфиг-файла используется yaml файл, по умолчанию имя файла docker-compose.yaml. И всё что вам нужно для работы с кучей контейнеров вы можете получить в одном файле, что даёт возможность управлять контейнеризацией быстрее и проще.
Для управление всем этим добром используется утилита docker-compose. Скорее всего вы уже слышали или еще услышите, что docker-compose не рекомендуется к использованию в боевой середе, мол только для разработки или тестов. Говорят, так потому что считается что лучше использовать для боевой среды kubernetes. И я с этим согласен, но что если вам нужно поднять всего с десяток контейнеров? Разве стоит ради этого создавать кластер kubernetes? Как по мне нет и вместо того чтобы вручную создавать каждый контейнер проще использовать docker-compose, ничего страшного я здесь не вижу.
файл docker-compose.yaml
Первое на что стоит обратить при разговоре про файл docker-compose.yaml это версионность. Файл docker-compose.yaml имеет версии, на данный момент это - 1, 2, 2.1, 3.2, 3.8. Каждая версия указывает на то какие ключи вы можете использовать при написании файла и какой синтаксис.
🥶docker-compose.yaml.version
version: '3.9'
services:
web:
image: nginx:latest
ports:
- "8080:80"
db:
image: postgres:15
environment:
POSTGRES_PASSWORD: example
С конца 2021 года Docker объединил Compose V2 и ввёл единый стандарт — Compose Specification. Теперь версию можно вовсе не указывать, пи обращению к файлу Docker сам определяет формат по структуре YAML-файла.
😊docker-compose.yaml
services:
web:
image: nginx:latest
ports:
- "8080:80"
db:
image: postgres:15
environment:
POSTGRES_PASSWORD: example
Но если вы просто пишите версию в файле наугад, то делаете неправильно. Версия файла, которую вы можете использовать зависит от версии вашего docker-compose.
docker compose version
Docker Compose version v2.27.0
Если же вдруг в выводе будет версия v1.x, то у меня для вас плохие новости новые версии использовать вы не сможете и придётся указывать версию руками в файле. А вообще сидеть сейчас на старом docker-compose нет никакого смысла.
Имя файла конечно же может быть и другим, но в таком случае при использовании команды docker-compose необходимо передать имя файла используя опцию -f.
Зачастую многие разработчики софта создают уже готовый docker-compose.yaml и размещают его на github. В таком случае конечному пользователю всего лишь необходимо скачать этот файл и создать все необходимые контейнеры для работы приложения, очень удобно и быстро.
файл docker-compose.yaml
Рассмотрим базовый docker-compose.yaml, который создаст два контейнера (app, db) в одной сети backend.
Обратите внимание на отступы, если не соответствовать иерархии (отступам), то при попытке создания контейнеров вы получите ошибку. Лучше использовать редакторы с возможностью анализировать структуру yaml файлов.
🪲docker-compose.yaml
# 📦 Раздел "services" — описывает контейнеры, которые будут запущены.
services:
app:
image: python:3.11-slim # образ контейнера
container_name: myapp # имя контейнера (опционально, dns name)
build: # если хочешь собрать из Dockerfile
context: . # путь к Dockerfile
dockerfile: Dockerfile
command: python app.py # команда, выполняемая при старте
working_dir: /usr/src/app # рабочая директория внутри контейнера
volumes:
- .:/usr/src/app # монтирование локальной папки
- app_data:/data # подключение именованного volume
ports:
- "8080:80" # проброс портов (host:container)
environment: # переменные окружения
- DEBUG=True
- DATABASE_URL=postgres://user:pass@db:5432/mydb
depends_on: # зависимости между контейнерами
- db
networks: # указание сетей
- backend
db:
image: postgres:15
restart: always # политика перезапуска
environment:
POSTGRES_USER: user
POSTGRES_PASSWORD: pass
POSTGRES_DB: mydb
volumes:
- pg_data:/var/lib/postgresql/data # подключение именованного volume
networks:
- backend
# 🗃️ Раздел "volumes" — хранение постоянных данных (не удаляются при stop).
volumes:
pg_data:
app_data:
# 🌐 Раздел "networks" — настройка сетей между контейнерами.
networks:
backend:
driver: bridge # тип сети (по умолчанию — bridge)
Создание контейнеров с помощью docker compose
Теперь когда есть готовый файл docker-compose.yaml нужно как-то создать контейнеры используя его. Для создания контейнеров используется docker compose, в более старых версиях docker-compose. Если у вас не установлен docker compose, то выполните установку docker-compose-plugin, более подробнее для RHEL и Ubuntu.
Для начала проверим что что можно сделать, используя docker compose вызвав справку ````docker compose –help```. Вот список наиболее часто используемых команд:
- down - остановка и удаление контейнеров и сетей
- exec - выполнение команды внутри контейнера
- logs - просмотр логов контейнера
- ps - просмотр списка контейнеров
- pull - скачивание образа для контейнера
- restart - перезапуск контейнера
- start - запуск контейнера
- stop - остановка контейнера
- top - просмотр процессов
- up - создание и запуск контейнеров
Как вы поняли из списка команды выше для создания контейнеров используется команда docker compose up.
Для начала я создам файл docker-compose.yaml с одним контейнером использующим образ nginx и выполню команду создания и запуска контейнеров.
🪲docker-compose.yaml
services:
mynginx:
image: nginx: 1.18
ports: 80:80
docker compose up -d
⠼ Network dockerfile_default Created
✔ Container dockerfile-mynginx-1 Started
Теперь я проверю что контейнер действительно запустился. Обратите внимание что docker compose ps и просто docker ps выведут разные списки. Дело в том, что docker compose работает только с контейнерами, которые описаны в файле.
docker compose ps
dockerfile-mynginx-1 nginx:1.18
docker ps
dockerfile-mynginx-1 nginx:1.18
ome-postgresql2 postgres:17.6
Остановка и удаление контейнеров с помощью docker compose
Если нужно просто остановить контейнеры, но сохранить их так же как ив аналогии с командой docker используется stop.
docker compose stop
✔ Container dockerfile-mynginx-1 Stopped
Если же нужно еще и удалить созданные контейнеры с помощью docker compose используется down, созданные volume при этом не удаляются.
docker compose down
✔ Container dockerfile-mynginx-1 Removed
✔ Network dockerfile_default Removed


Комментарии