XNOVA
← Все статьи

СТАТЬЯ / engineering

Команды Docker Compose: up, down, build, logs, exec — шпаргалка

Как выбрать команду Docker Compose для запуска, сборки, просмотра журналов, работы внутри контейнера и остановки проекта — на одном примере с проверкой результата.

Автор: XNova

Вы поправили HTML-страницу, пересобрали Docker-образ, открыли браузер — а там по-прежнему старый текст. Причина может быть в файле, кэше или в том, что контейнер не обновился. За каждый шаг отвечает своя команда Docker Compose.

Эта шпаргалка поможет быстро выбрать нужную команду и разобраться в её результате. Сначала — таблица для повседневной работы. Затем на одном небольшом проекте посмотрим, как up, build, logs, exec и down связаны друг с другом.

Для повторения понадобятся работающий Docker Engine или Docker Desktop, плагин docker compose, редактор и curl. Команды рассчитаны на Linux/macOS; на Windows нужен терминал, в котором доступны docker и curl. Если образ Nginx ещё не загружен, потребуется доступ к реестру.

Проверьте окружение:

docker compose version
docker info

Первая команда проверяет доступность Compose, вторая — соединение с Docker Engine. Если docker info не работает, сначала запустите движок или настройте доступ к нему. Дальше мы предполагаем, что вы уже знакомы с контейнерами и базовым устройством compose.yaml.

Команды Docker Compose: короткая шпаргалка

ЗадачаКомандаЧто произойдёт
Запустить сервисыdocker compose up -dCompose создаст или запустит контейнеры и при необходимости пересоздаст изменившиеся.
Пересобрать образdocker compose build webОбновится образ сервиса web. Уже работающий контейнер останется прежним.
Посмотреть журналdocker compose logs --tail=20 webПоявятся последние сообщения сервиса, если они есть.
Прочитать файл внутри контейнераdocker compose exec -T web cat /usr/share/nginx/html/index.htmlcat выведет HTML из запущенного контейнера.
Остановить проект и убрать контейнерыdocker compose downCompose остановит и удалит контейнеры сервисов и сети проекта по умолчанию.

Рядом с этими командами полезно помнить ещё две: docker compose config -q проверяет описание сервисов, а docker compose ps показывает, что запущено. Проверить, отвечает ли приложение по HTTP, они не могут.

Различие такое: build собирает образ, а up запускает и обновляет контейнеры. Если вы изменили Dockerfile или файлы для сборки, можно сначала выполнить build, затем up. Команда up -d --build позволяет сделать обе операции за один шаг.

Пример: Nginx и собственный Dockerfile

Чтобы почувствовать разницу между сборкой и запуском, сделаем страницу, которую Nginx будет отдавать из собственного образа. Для этого хватит трёх файлов. Создайте каталог compose-commands:

mkdir -p compose-commands/site
cd compose-commands

Структура получится такой:

compose-commands/
├── compose.yaml
├── Dockerfile
└── site/
    └── index.html

Создайте compose.yaml:

name: xnova-compose-commands
services:
  web:
    build: .
    ports:
      - "127.0.0.1:8082:80"

В Dockerfile укажите базовый образ и файл страницы:

FROM nginx:stable-alpine@sha256:0e52bd054126cdc040b1276c0af347aeb02a41b9cfe305d6094767ac30e97949
COPY site/index.html /usr/share/nginx/html/index.html

Наконец, сохраните site/index.html:

<!doctype html>
<html lang="ru">
  <head><meta charset="utf-8"><title>Compose commands</title></head>
  <body><h1>Команды Compose работают</h1></body>
</html>

Что здесь происходит? В compose.yaml поле build: . задаёт каталог сборки. Инструкция FROM выбирает образ Nginx, а COPY помещает HTML в каталог, из которого Nginx обслуживает статические файлы. О назначении инструкций можно прочитать в справке Dockerfile и описании образа Nginx.

Порт 8082 вашего компьютера связан с портом 80 контейнера. Адрес 127.0.0.1 ограничивает обычный локальный доступ к опубликованному порту; если 8082 занят, измените левую часть записи на свободный порт и используйте его в HTTP-запросах ниже.

При технической проверке Docker Engine 24.0.6 и Compose 2.22.0 собрали этот Dockerfile на linux/arm64; запрос к порту 8082 вернул исходный HTML и HTTP 200.

docker compose up: запустить сервис

Перейдите в каталог compose-commands, если ещё не сделали этого. Сначала проверим конфигурацию, затем соберём образ и запустим Nginx:

docker compose config -q
docker compose up -d --build
docker compose ps
curl -fsS http://127.0.0.1:8082/

config -q проверяет конфигурацию и при успешном завершении ничего не выводит. up -d --build собирает образ перед запуском и оставляет контейнер в фоне: -d означает detached mode, а --build явно включает сборку. Если базового образа ещё нет, Docker сначала загрузит его из реестра.

Посмотрите на результаты отдельно. docker compose ps должен показать работающий сервис web и опубликованный порт. А HTTP-запрос должен вернуть страницу с заголовком Команды Compose работают. Это две разные проверки: контейнер может находиться в состоянии Up, даже если приложение не отвечает так, как мы ожидаем.

Можно выполнить docker compose up и без -d. Тогда вывод контейнеров останется в текущем терминале, а при завершении команды контейнеры будут остановлены. Для дальнейших примеров удобнее запуск в фоне. Флаги и условия пересоздания подробно описаны в справке up.

Если позже поменяется конфигурация сервиса или его образ, повторный up при необходимости пересоздаст контейнер. Сейчас проверим это поведение отдельно.

docker compose build: пересобрать образ

Сервис работает. Теперь измените в site/index.html заголовок:

<h1>Команды Compose: версия 2</h1>

Сохраните файл и выполните:

docker compose build web
curl -fsS http://127.0.0.1:8082/

docker compose build web собирает образ сервиса web, но не подменяет работающий контейнер. Поскольку мы использовали COPY, старый контейнер продолжит отдавать прежнюю страницу: сборка подготовила новый образ, но не перевела на него существующий процесс.

Это и есть важное наблюдение. Изменённый HTML уже попал в новый образ, но HTTP-запрос всё ещё обращается к прежнему контейнеру. Чтобы применить результат сборки, выполните:

docker compose build создаёт новый образ, но работающий контейнер остаётся прежним до docker compose up; logs и exec работают с запущенным контейнером, а down удаляет контейнер и сеть, сохраняя тома без флага -v.

docker compose up -d
curl -fsS http://127.0.0.1:8082/

Теперь ожидается заголовок Команды Compose: версия 2. Compose обнаруживает изменившийся образ и пересоздаёт контейнер. Если же входные файлы не менялись, сборка может использовать кэш и пересоздание не потребуется.

Вернуть первоначальную страницу можно тем же способом: восстановите заголовок в site/index.html, затем снова выполните docker compose build web и docker compose up -d. Одного редактирования файла недостаточно: в этом проекте HTML копируется внутрь образа при сборке, а не подключается как каталог с компьютера.

Параметр --no-cache отключает использование кэша сборки, а --pull запрашивает обновление базового образа. Без необходимости применять их при каждом запуске не нужно. Подробности — в справке build.

docker compose logs: посмотреть сообщения приложения

Когда контейнер запущен, журналы помогают понять, что происходило внутри сервиса. Например, после запроса к Nginx посмотрите последние записи:

docker compose logs --tail=20 web

--tail=20 ограничивает вывод последними двадцатью строками. Вы увидите сообщения сервиса, если он их записал. Формат и число строк зависят от образа, событий и настроек журналирования; здесь не нужно ожидать конкретную строку, которой может не оказаться.

Если важно наблюдать за новыми запросами, откройте второй терминал и выполните:

docker compose logs -f web

В первом терминале снова отправьте HTTP-запрос. Во втором должны появляться новые записи, если Nginx выводит их в стандартные потоки контейнера. Остановить просмотр журнала можно сочетанием Ctrl+C: запущенный через up -d контейнер от этого не останавливается. Это поведение следует из описания logs.

Логи полезны для поиска причины, но не заменяют HTTP-проверку. Сообщение о запуске Nginx не доказывает, что конкретный запрос возвращает нужную страницу.

docker compose exec: посмотреть, что внутри контейнера

Когда локальный файл и страница в браузере не совпадают, полезно проверить содержимое работающего контейнера напрямую:

docker compose exec -T web cat /usr/share/nginx/html/index.html

exec запускает программу в уже работающем контейнере сервиса web. Команда cat напечатает HTML, который Nginx получает из файловой системы контейнера. Сравните его с локальным site/index.html и ответом curl. Так можно понять, дошло ли изменение до запущенного сервиса.

Ключ -T отключает выделение псевдотерминала, что удобно для обычной проверки или CI. Если нужно осмотреть несколько файлов вручную, откройте оболочку:

docker compose exec web sh

Эта команда сработает, если в образе есть sh и контейнер запущен. Для неинтерактивной проверки лучше использовать конкретную команду вроде cat, а не оболочку. Остальные параметры есть в документации exec.

После down или до первого запуска контейнера команда exec не сработает. Сначала проверьте состояние через docker compose ps и при необходимости выполните docker compose up -d.

docker compose down: завершить работу и удалить ресурсы проекта

После проверки полезно убрать созданные Compose ресурсы, чтобы не оставлять работающий сервис и занятый порт:

docker compose down
docker compose ps --all

По умолчанию down останавливает и удаляет контейнеры сервисов и сети проекта, но не удаляет папку исходников и собранные образы. Если после команды ps --all не показывает контейнеров этого проекта, очистка завершена. Файлы compose.yaml, Dockerfile и site/index.html останутся на компьютере.

down отличается от stop: остановленный через stop контейнер сохраняется и может быть снова запущен командой start. После down обычный путь восстановления — up, который создаст новый контейнер.

Будьте внимательны с удалением данных. По умолчанию down не удаляет именованные и анонимные тома. Параметр -v добавляет удаление именованных томов, объявленных в Compose-файле, и анонимных томов контейнеров; параметр --rmi отдельно управляет удалением образов. В нашем примере данных в томах нет, но в проекте с базой данных эти ключи требуют отдельного решения. Правила подробно описаны в справке down.

Если команда не сработала

При сбое ищите причину на том шаге, где результат перестал совпадать с ожидаемым.

  1. Ошибка в config -q. Посмотрите отступы в YAML и значения services, build, ports. Исправьте файл, затем снова проверьте конфигурацию — до запуска контейнеров.
  2. Не проходит build web. Убедитесь, что Dockerfile лежит в каталоге сборки, существует site/index.html и доступен базовый образ. После исправления повторите сборку.
  3. Не запускается up -d. Выполните docker compose ps --all и посмотрите сообщения сервиса. Если занят порт 8082, выберите свободный порт слева от :80 в compose.yaml и измените адрес HTTP-запроса.
  4. curl показывает старую страницу. Прочитайте файл через docker compose exec -T web cat /usr/share/nginx/html/index.html. Если в контейнере старый HTML, пересоберите образ и выполните up -d.
  5. exec сообщает, что сервис не работает. Посмотрите docker compose ps. Сначала запустите контейнер, а уже затем выполняйте команды внутри него.

Если logs пуст, это ещё не означает, что приложение неисправно: проверьте, отправляли ли вы запрос и выводит ли сервис сообщения в журнал. Проверку HTTP всё равно делайте через curl.

Итог простой: build готовит образ, up запускает или обновляет контейнеры, logs показывает их сообщения, exec помогает проверить содержимое, а down убирает ресурсы проекта. Этого достаточно для обычного цикла локальной работы. Безопасность, устойчивость к нагрузке и сохранность данных потребуют отдельных проверок.

Источники