Docker Compose: шпаргалка команд для сервера
Понад 40 підкоманд Compose, але щодня потрібні близько 12: запуск, зміни, логи, shell, мережі, volumes і безпечне очищення.
Команди Compose, які ви використовуватимете найчастіше
Docker Compose має понад сорок підкоманд. У щоденній роботі на сервері зазвичай потрібні близько дванадцяти. На цій сторінці вони згруповані за завданнями, які ви виконуєте. Для кожної команди наведено просте пояснення, а також посилання на детальний матеріал, якщо команда має неочевидні особливості.
Усі приклади використовують Compose V2: docker compose із пробілом, а не старий скрипт docker-compose. V2 — це плагін на Go, який встановлюється разом із Docker Engine. V1 вилучено з актуальних пакетів, тому docker-compose: command not found у щойно встановленій Ubuntu станом на July 2026 є очікуваною поведінкою, а не ознакою несправності. Перевірте це за допомогою docker compose version. Якщо команда нічого не виводить, установіть пакет docker-compose-plugin.
Усі наведені нижче команди потрібно виконувати з каталогу, у якому міститься ваш compose.yaml, оскільки Compose визначає назву проєкту за цим каталогом і шукає файл відносно нього. Якщо виконати ту саму команду на один рівень вище, Compose завершиться з помилкою no configuration file provided: not found. Якщо формат самого файлу вам ще незнайомий, почніть із матеріалу перший файл Compose на VPS, а потім поверніться сюди до команд.
Життєвий цикл: чотири команди, які ви вводите, і команда, що видаляє контейнери
docker compose up -d
docker compose up -d --wait
docker compose stop
docker compose start
docker compose restart web
docker compose downup -d створює мережу, створює контейнери, запускає їх і завершує роботу. Команда завершується одразу після створення контейнерів. Тому скрипт розгортання, який після неї виконує перевірку через curl, часто завершується помилкою під час першої спроби. up -d --wait очікує, доки кожен сервіс із визначеною healthcheck не повідомить про стан healthy, і завершується з ненульовим кодом, якщо цього не відбувається. Прапорець працює настільки добре, наскільки добре налаштована перевірка, що стоїть за ним. Тому перед використанням цієї можливості в автоматизації налаштуйте healthcheck, якому може довіряти Compose.
stop зупиняє контейнери, але зберігає їх. Тому start запускає ті самі контейнери з тим самим доступним для запису шаром. down зупиняє контейнери, а потім видаляє їх і мережу проєкту. Усе, що записано всередині контейнера, але не у volume, буде втрачено разом із контейнерами. Це найсуттєвіше непорозуміння під час роботи з Compose. У матеріалі повна різниця між down і stop описано, у яких випадках це створює проблему.
restart не виконує перезавантаження конфігурації. Команда зупиняє та запускає той самий контейнер із уже наявною конфігурацією. Тому змінна середовища, новий тег образу або змінене зіставлення портів не матимуть жодного ефекту. Щоб застосувати зміни у файлі, знову виконайте up -d. Compose порівнює кожен сервіс із запущеним контейнером і повторно створює лише ті контейнери, конфігурація яких змінилася.
Застосування змін: повторне створення, завантаження або збирання
docker compose up -d --force-recreate
docker compose pull && docker compose up -d
docker compose build --no-cache web
docker compose up -d --build webup -d нічого не робить, якщо нічого не змінилося. Саме тому цю команду безпечно виконувати повторно. --force-recreate ігнорує це порівняння та замінює кожен контейнер, навіть якщо конфігурація ідентична. Це найшвидший спосіб усунути нетиповий стан усередині контейнера.
Оновлення image потребує двох команд, оскільки вони виконують різні дії. pull завантажує поточний image для кожного tag, указаного у файлі. Потім up -d виявляє, що ID image сервісу більше не відповідає його запущеному контейнеру, і повторно створює цей контейнер. Якщо пропустити завантаження, up -d без помилки продовжить використовувати торішній latest. Протилежний ризик виникає у stack із кількома сервісами: одночасне завантаження latest для кожного сервісу може зламати застосунок, який працював десять секунд тому. Саме тому self-hosted робочий простір AFFiNE натомість фіксує кожен із чотирьох tag image.
build застосовується до сервісів, у яких оголошено секцію build:, а не image:. up -d --build виконує збирання та запуск одним кроком. Це стандартний цикл під час зміни коду. Використовуйте --no-cache лише тоді, коли кешований layer явно застарів, оскільки ця команда повторно збирає кожен layer з нуля.
Що запущено
docker compose ps
docker compose ps -a
docker compose logs -f --tail=100
docker compose logs --since 15m --timestamps db
docker compose top
docker compose lsps показує лише запущені контейнери. Сервіс, який аварійно завершився під час запуску, не відображається, доки не додати -a. Тому контейнер, якого немає у ps, але який ps -a показує як Exited (1), — це типовий вигляд помилки запуску. Перевірте код завершення, а потім журнали.
logs -f одночасно відстежує всі сервіси та додає до кожного рядка назву сервісу. Це потрібне представлення, коли сервіси взаємодіють між собою і важливий порядок подій. Щоб звузити виведення, укажіть назву сервісу. --tail=100 потрібен для контейнера, який працює вже місяць, оскільки за замовчуванням виводиться вся історія, що переповнює термінал. --since 15m відповідає на запитання, яке зазвичай виникає: що сталося під час щойно виконаного перезапуску.
top показує процеси всередині кожного контейнера. Це дає змогу відрізнити ситуацію, коли контейнер працює, від ситуації, коли процес усередині нього працює. ls виходить за межі поточного каталогу та показує всі проєкти Compose на хості разом із їхнім станом. Так можна знайти стек, який ви запустили три місяці тому.
Отримання shell усередині сервісу
docker compose exec web sh
docker compose exec -u root web sh
docker compose run --rm web env
docker compose run --rm --no-deps web shexec виконує команду всередині контейнера, який уже запущений. run запускає новий контейнер на основі того самого визначення сервісу. Це потрібно, коли сервіс працює недостатньо довго для виконання команди через exec. Завжди використовуйте run разом із --rm. Інакше кожен запуск залишатиме після себе зупинений контейнер, і з часом їх стане так багато, що docker compose ps -a буде важко читати.
Спочатку спробуйте sh, а не bash. Образи на основі Alpine не містять bash, тому помилка має вигляд exec: "bash": executable file not found in $PATH. Додавання --no-deps до run пропускає залежності сервісу. Завдяки цьому швидка перевірка конфігурації не запускає всю базу даних.
run --rm web env — найшвидший спосіб перевірити середовище, яке фактично отримав сервіс, після об’єднання всіх файлів .env, блоків environment: і змінних shell. Якщо значення неправильне, причиною зазвичай є порядок об’єднання. У матеріалі як Compose обробляє env-файли та секрети описано, яке джерело має пріоритет.
Мережі, порти та визначення імен
docker compose port web 80
docker compose exec web getent hosts db
docker compose config --networksCompose розміщує всі сервіси в одній мережі проєкту, а ім’я кожного сервісу є DNS-ім’ям у цій мережі. Виконання getent hosts db всередині web виводить IP-адресу контейнера, якщо ім’я визначається, і не виводить нічого, якщо визначення не працює. Тому за дві секунди можна перевірити, чи бачать ці контейнери один одного. Якщо ім’я визначається, але підключення відхиляється, процес усередині db прив’язаний до 127.0.0.1, а не до 0.0.0.0. Тому він не приймає пакети з іншого контейнера. Докладніше цю модель описано в матеріалі як працюють мережі Compose і DNS сервісів.
port web 80 виводить адресу хоста та порт, на який опубліковано порт контейнера. Це усуває потребу вгадувати значення, коли зіставлення задано змінною. Публікація порту також створює правило брандмауера, яким Docker керує самостійно. Це правило має вищий пріоритет за ваше правило. Тому сервіс, який ви вважали приватним, може стати доступним з інтернету. Цей випадок розглянуто в матеріалі чому опубліковані порти Docker обходять ufw. Безпечніша схема — не публікувати ці порти, а розмістити перед сервісами один proxy із автентифікацією в мережі проєкту. Саме це забезпечує запуск Authentik як рівня єдиного входу.
Томи та дані
docker compose config --volumes
docker compose cp db:/etc/postgresql/pg_hba.conf ./pg_hba.conf
docker compose down -vconfig --volumes виводить іменовані томи, оголошені проєктом, по одному в кожному рядку. Саме цей список потрібно резервно копіювати. Якщо томи містять дані, які неможливо відновити, точна команда резервного копіювання не менш важлива, ніж сам список. Тому в порівнянні PhotoPrism та Immich наведено команди для створення дампу й копіювання, потрібні кожному фотосерверу. cp копіює файл у контейнер або з контейнера без відкриття shell, використовуючи форму service:path з того боку, де розташований контейнер.
down -v видаляє ці іменовані томи разом із контейнерами. Це правильна команда для видалення тестового стека, але неправильна для всього, що містить важливі для вас дані, оскільки команда не запитує підтвердження і не має операції скасування. Bind mounts переживають це видалення, оскільки розташовані у файловій системі хоста. Ця різниця в масштабі можливих наслідків є однією з причин свідомо обирати між bind mounts та іменованими томами.
Очищення, яке звільняє місце на диску без втрати даних
docker compose down --remove-orphans
docker system df
docker image prune -a
docker builder prune--remove-orphans видаляє контейнери, що належать проєкту, але більше не зазначені у файлі. Саме це відбувається після перейменування сервісу. Без цього такі контейнери продовжують працювати, а docker compose ps їх не показує.
docker system df показує, скільки місця на диску займають різні об’єкти, перш ніж щось видаляти. Команда окремо враховує образи, контейнери, локальні томи та кеш складання й для кожного показує обсяг, який можна звільнити. image prune -a видаляє всі образи, на які не вказує жоден тег. На сервері, де завантажено кілька версій великого образу, це зазвичай дає найбільший результат. builder prune очищає кеш складання, який непомітно зростає на кожному сервері, де створюються власні образи.
Жодна з цих команд не змінює іменований том. Лише docker volume prune і docker compose down -v працюють із ним.
Перевірка файлу до того, як він спричинить проблему
docker compose config --quiet
docker compose config --services
docker compose --dry-run up -dconfig --quiet перевіряє файл і не виводить нічого в разі успіху, тому цю команду слід використовувати на етапі перед розгортанням або в git hook. Звичайна команда config виводить повністю об’єднаний файл після підстановки змінних. Так можна перевірити, чи змінну успішно підставлено та чи файл перевизначень додано в потрібному порядку. Невизначена змінна відображається як порожнє значення поруч із попередженням The "X" variable is not set. Defaulting to a blank string.
--dry-run є глобальним прапорцем, а не прапорцем підкоманди, тому його потрібно вказувати перед up. Команда виводить кожну дію, яку виконав би Compose, і нічого не змінює. Це тридцять секунд, які варто витратити перед виконанням down для важливого стека.
Робота з файлами, профілями та проєктами
docker compose -f compose.yaml -f compose.prod.yaml up -d
docker compose --profile debug up -d
docker compose -p staging up -dКілька прапорців -f об’єднуються послідовно, а пізніші файли перевизначають ключі з попередніх. Це стандартний спосіб зберігати один базовий файл із невеликим перевизначенням для production. Однак правила відрізняються для списків і мап, тому перед пошуком причини неочікуваної поведінки перегляньте як Compose об’єднує кілька файлів.
--profile запускає сервіси, позначені цим профілем, разом із сервісами без профілю. Це дає змогу не включати інструменти налагодження до звичайного up. -p задає назву проєкту, тому дві копії одного стека можуть працювати паралельно з окремими мережами та окремими назвами томів. Відновлення стека після перезавантаження не потребує введення команди. Для цього використовується unit, який запускає стек автоматично. Його описано в розділі запуск стеків Compose під час завантаження.
FAQ
Що замінило docker-compose із дефісом?
Compose V2, який викликають як docker compose із пробілом. Це плагін, що постачається разом із Docker Engine, а інструмент V1 на Python більше не встановлюється актуальними пакетами. Якщо форма з пробілом нічого не виводить, встановіть пакет docker-compose-plugin для свого дистрибутива. Оновлюйте старі скрипти до форми з пробілом, а не додавайте alias, оскільки V2 має прапорці, яких ніколи не мав V1.
Чому docker compose restart не застосовує мою зміну конфігурації?
restart зупиняє та запускає наявний контейнер із конфігурацією, з якою його було створено, і ніколи не перечитує compose.yaml. Будь-яка зміна змінних середовища, портів, томів або тегу образу потребує docker compose up -d. Ця команда порівнює кожен сервіс із його запущеним контейнером і повторно створює ті, що відрізняються. Додайте --force-recreate, якщо потрібно виконати заміну, навіть коли у файлі нічого не змінилося.
Як оновити сервіс до новішого образу?
Виконайте docker compose pull, а потім docker compose up -d. Команда pull завантажує поточний образ для кожного тегу у файлі, а up -d повторно створює всі сервіси, ідентифікатор образу яких більше не збігається з ідентифікатором їхнього контейнера. Самостійний запуск up -d повторно використовує образ, який уже збережено на диску. Через це стек, зафіксований на latest, може працювати на збірці, якій кілька місяців, і не виводити жодної помилки.
Які команди очищення безпечні на робочому сервері?
docker system df, docker image prune -a і docker builder prune видаляють лише образи та кеш. Запущені сервіси продовжують працювати, а іменовані томи не змінюються. Небезпечно використовувати docker compose down -v і docker volume prune, оскільки вони видаляють іменовані томи без запиту на підтвердження. Спочатку виконайте docker compose config --volumes, щоб визначити, що саме може бути видалено.
Чи можна виконати одну команду, не запускаючи весь стек?
Так. docker compose run --rm --no-deps web sh запускає один контейнер із визначенням сервісу web, не запускає його залежності та видаляє контейнер після завершення роботи. Якщо контейнер уже запущений, використовуйте exec, оскільки exec підключається до активного процесу й показує фактичний стан сервісу.