0% прочитано

Чому оновлений Docker-образ ще не гарантує, що Laradock запустить саме його

Оновити або зібрати безпечніший Docker-образ недостатньо. Потрібно перевірити фактичну Compose-конфігурацію, image reference, immutable image ID і всі override-файли, інакше наступний запуск може знову використати старий образ.

1 листопада 2026 р. 10 хв читанняLaradock

Після security-оновлення легко отримати новий Docker-образ, перевірити в ньому потрібну версію PHP і вирішити, що проблема закрита.

Але Docker Compose запускає не абстрактно "найновіший образ". Він використовує конфігурацію, яка вийшла після об’єднання Compose-файлів, змінних середовища, image, build та override.

У моєму локальному Laradock це стало окремою частиною перевірки: після підготовки виправлених PHP-FPM, workspace і phpMyAdmin образів потрібно було довести, що наступний запуск не поверне старі image references.

Новий образ і фактична Compose-модель - це різні речі

Docker image може вже існувати локально і навіть успішно пройти перевірки. Це ще не означає, що сервіс описаний у Compose саме через цей image reference.

Сервіс може мати старий image:, залишений build:, інший override або запускатися через іншу комбінацію -f файлів.

Тому після підготовки нового образу я перевіряю не тільки сам image, а й те, що Docker Compose реально бачить після злиття конфігурації.

Спочатку перевіряємо, що Compose-конфігурація валідна

Перевірка Compose-конфігурації
cd ~/Projects/laradock || exit 1 docker compose config -q

docker compose config -q не запускає контейнери. Він перевіряє, чи може Docker Compose зібрати конфігурацію без синтаксичних і частини структурних помилок.

Для security-зміни це важливий перший guard: якщо override написаний неправильно, немає сенсу переходити до recreate контейнерів.

Дивимося, які образи Compose справді збирається використовувати

Образи з фактичної Compose-конфігурації
cd ~/Projects/laradock || exit 1 docker compose config --images

Ця команда значно корисніша за простий docker image ls, коли потрібно відповісти на запитання: "Що саме Compose планує використати?"

docker image ls показує, що є локально. docker compose config --images показує image references, які вийшли з Compose-моделі.

Якщо оновлений образ є локально, але його немає в результаті config --images, він сам по собі нічого не виправляє.

Якщо використовуються кілька Compose-файлів, перевіряємо саме їхню комбінацію

Найнебезпечніша помилка тут - перевірити один Compose-файл, а запускати середовище іншою командою.

Якщо Laradock використовує базовий файл і кілька override, усі перевірки повинні повторювати той самий набір -f, який буде використано для наступного запуску.

Приклад перевірки тієї самої багатофайлової Compose-моделі
docker compose \  -f docker-compose.yml \  -f docker-compose.override.yml \  -f docker-compose.local.yml \  -f docker-compose.security-php.yml \  config -q docker compose \  -f docker-compose.yml \  -f docker-compose.override.yml \  -f docker-compose.local.yml \  -f docker-compose.security-php.yml \  config --images
Назви додаткових Compose-файлів залежать від конкретного проєкту. Принцип незмінний: перевірка і запуск повинні використовувати однаковий набір файлів у тому самому порядку.

Image tag недостатньо: фіксуємо immutable image ID

Tag зручний для людини, але він не є незмінною ідентичністю образу. Сьогодні my-php:8.5-secure може вказувати на один image ID, а після rebuild той самий tag уже вказуватиме на інший.

Тому під час контрольованого security-оновлення я фіксую і tag, і immutable image ID.

Tag і immutable image ID
docker image inspect \  --format '{{.RepoTags}} | id={{.Id}}' \  my-php:8.5-secure

Перевіряємо, який image ID реально використовує контейнер

Фактичний образ контейнера
docker inspect \  --format 'name={{.Name}} image={{.Config.Image}} image_id={{.Image}} state={{.State.Status}}' \  laradock-php-fpm-85-1

Тут важливо порівняти три речі:

  1. який image reference дає docker compose config --images;
  2. на який image ID зараз вказує цей tag;
  3. який image ID реально має контейнер.

Лише збіг цих даних дає зрозумілу картину поточного стану.

Чому build може знову змінити результат

Навіть якщо image: уже вказує на потрібний образ, активний build: може змінити поведінку наступної команди залежно від способу запуску.

У моєму випадку безпечний override був навмисно побудований так, щоб для потрібних PHP-сервісів ефективна модель містила зафіксовані image references, а небажаний rebuild не повертав стару базу.

Швидка перевірка image і build у злитій моделі
docker compose config \  | grep -nE '^[[:space:]]+(image|build):'
Повний вивід docker compose config може містити чутливі environment values. Не варто публікувати його без перевірки. Для статті достатньо показувати вузькі вибірки або санітизований результат.

Постійний override важливіший за одноразовий успішний запуск

Одноразово запустити контейнер на правильному image ID недостатньо. Якщо наступного дня звичайний docker compose up не підключить потрібний override, середовище може повернутися до старого image reference або знову піти в build.

Саме тому image pin має бути частиною повторюваної Compose-конфігурації, а не лише ручною командою під час аварійного оновлення.

Перевіряємо різницю до будь-якого recreate

Перед recreate я хочу бачити мінімальну очікувану зміну: для потрібних PHP-сервісів змінилися image references, а інші сервіси, порти, volumes і мережі залишилися без несподіваних змін.

Це хороший момент зберегти санітизований effective config до і після зміни та порівняти їх.

Фіксуємо список образів після зміни конфігурації
docker compose config --images \  | sort \  > /tmp/compose-images.after.txt cat /tmp/compose-images.after.txt

Що я перевіряю перед наступним запуском

Перед будь-яким mutating Compose-запуском у мене має бути відповідь на кілька конкретних запитань:

  • чи валідний потрібний набір Compose-файлів;
  • чи показує config --images саме оновлені image references;
  • чи відомі immutable image IDs цих образів;
  • чи немає небажаного build: для сервісів, які повинні використовувати готові images;
  • чи не змінює override unrelated ports, volumes або інші сервіси;
  • чи буде наступна команда використовувати той самий набір -f файлів.

Безпечний Docker-образ не допомагає, якщо фактична Compose-конфігурація під час наступного запуску вибере інший образ.

Підсумок

У security-оновленні Docker важливо розділяти два факти: "я створила виправлений образ" і "Laradock гарантовано використає його". Це не одне й те саме.

Мій практичний висновок простий: після оновлення образів потрібно перевірити effective Compose-модель, image references, immutable image IDs і постійний override. І лише після цього переходити до контрольованого recreate контейнерів.

Наступна проблема, яку варто розібрати окремо: чому Docker Compose іноді піднімає більше сервісів, ніж очікуєш, навіть коли команда здається локальною і точковою.