До основного вмісту

PHP у Docker: як закрити PHP2Shell перезбиранням образу

PHP · 27.10.2026 · 2 хв читання

Коротко

Оновлення пакетів на хост-системі не зачіпає PHP усередині контейнера. Потрібно взяти свіжий базовий образ, зібрати свій заново та перезапустити контейнери. Перевіряти версію слід усередині контейнера, а не на хості.

Крок 1. Зрозуміти, що у вас усередині

docker ps --format '{{.Names}}\t{{.Image}}'
docker exec -it назва_контейнера php -v
docker exec -it назва_контейнера sh -c 'dpkg -l | grep php || rpm -q php-cli'

Офіційні образи PHP зібрано з вихідного коду, тому номер версії там чесний: 8.3.36 і новіша — виправлено, 8.3.35 і старіша — ні.

Крок 2. Оновити базовий образ

Якщо в Dockerfile закріплено точний тег, підніміть його до виправленої версії:

FROM php:8.3.36-fpm-bookworm

Якщо тег плаваючий (php:8.3-fpm), достатньо завантажити образ заново:

docker pull php:8.3-fpm
docker compose build --pull --no-cache
docker compose up -d

Прапорець --pull тут ключовий: без нього збірка візьме старий шар із локального кешу, і вразливість залишиться.

Крок 3. Перевірити результат

docker compose exec php php -v
docker compose exec php php -r 'echo PHP_VERSION, PHP_EOL;'

Версія має бути не нижчою за 8.3.36 для гілки 8.3, 8.4.27 для 8.4, 8.5.12 для 8.5, 8.2.35 для 8.2.

Крок 4. Переконатися, що старі контейнери не працюють

Часта помилка: образ оновлено, а поруч працює контейнер, запущений тиждень тому.

docker ps --format '{{.Names}}\t{{.Image}}\t{{.CreatedAt}}'

Якщо контейнер створено раніше, ніж ви перезібрали образ, створіть його заново.

Щоб не повторилося

  • Закріплюйте точні теги версій — так видно, що саме розгорнуто.
  • Перезбирайте образи за розкладом, а не лише під час правки коду: базовий образ старіє сам по собі.
  • Додайте в конвеєр перевірку вразливостей образу: docker scout cves назва_образу або trivy image назва_образу.

Часті запитання

Чи потрібно оновлювати PHP на хості, якщо все в контейнерах?

Якщо на хості PHP не використовується — ні. Але перевірте: утиліти на кшталт composer або скрипти cron могли притягнути системний PHP.

Чи образ на Alpine теж вразливий?

Так, вразливий сам код PHP, а не дистрибутив. Оновлювати потрібно так само.

Як швидко перевірити весь парк контейнерів?

for c in $(docker ps -q); do printf '%s ' "$(docker inspect -f '{{.Name}}' $c)"; docker exec $c php -v 2>/dev/null | head -1 || echo 'без php'; done
Чи була стаття корисною?
← Назад до бази знань Поставити питання підтримці