Понадобилось расширение PHP для Redis. Простой вопрос — «что сейчас в образе и как его пересобрать» — оказался без ответа: Dockerfile образа был утрачен, состав пришлось восстанавливать по слоям. После этого Dockerfile лежит в git, а сборка заняла шесть попыток — каждая грабля теперь записана прямо в нём.

Это пятая часть цикла «Сервер для WordPress».

Почему вообще свой образ

Официальный образ PHP с Docker Hub хорош, пока хватает его расширений. Нам нужны ещё ffmpeg для обложек видео и phpredis для кэша, и ставить их при каждом запуске контейнера — значит ждать минуты и зависеть от того, доступны ли сейчас зеркала пакетов. Свой образ собирается один раз и лежит в реестре.

Правило: Dockerfile в git

Образ без исходника — чёрный ящик. Чтобы добавить одно расширение, нужно знать всё остальное, что в нём есть, а узнать это можно только раскопкой слоёв. Теперь образ устроен в два этажа:

ТегЧто внутри
php:8.3-media-utils-extendбаза + ffmpeg и ffprobe (исходник этого этажа утрачен)
php:8.3-media-utils-extend-redisповерх: phpredis 6.2.0, igbinary, msgpack; PHP 8.3.24

Второй этаж собирается поверх первого — бинарники ffmpeg живут только в нём. Новые изменения — только через Dockerfile в git, никаких «зашёл в контейнер и доставил».

Потолок версии — не там, где ждёшь

Образ построен на Fedora 40 с PHP из репозитория remi. Кажется, что версию PHP ограничивает репозиторий. Нет: для Fedora 40 там есть всё от 8.0 до 8.4. Потолок 8.4 держит сама база — выше только со сменой системы, а база чужая и её исходников у нас нет. Цена зависимости от чужого образа видна только тогда, когда захочешь сделать шаг дальше.

Шесть граблей сборки

  1. --resolve — опция dnf download, а не dnf install;
  2. dnf download в Fedora 40 требует плагина: dnf install 'dnf-command(download)';
  3. пакеты PHP связаны точной версией: обновить одну библиотеку нельзя, обновлять весь набор — у нас 15 пакетов;
  4. dnf download тянет и 32-битные пакеты, а rpm потом требует 32-битную glibc, которой в образе нет. Лечится --arch x86_64,noarch;
  5. обновление libzstd ломает libzstd-devel; расширению хватает уже установленной версии;
  6. часть пакетов уже нужной версии, и rpm -Uvh без --replacepkgs на них падает.

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

Реестр и токен

# логин — имя пользователя в GitLab, токен — со scope read_registry и write_registry
docker login registry.gitlab.com -u <логин> --password-stdin < token.txt
  • токен подавать через --password-stdin, а не флагом -p — иначе он останется в истории оболочки;
  • первая отправка может упасть с blob unknown to registry — это сбой реестра, лечится повтором.

Как добавить расширение теперь

  1. дописать пакет в список в Dockerfile;
  2. собрать, проверить php -m в новом образе;
  3. отправить в реестр с новым тегом;
  4. сменить тег в compose сайта и пересоздать контейнер PHP — сначала на тесте.

На сервере образ, про который никто не знает, что в нём?

Пришлите, что используете, — соберу образ с Dockerfile в git и понятной процедурой обновления.

· полезно?
АЧ
Алексей Чикун веб-разработчик, команда TRIOHEAD

Делаю сайты и сервисы целиком: от вёрстки до сервера. Пишу о том, что проверил на своих проектах.

Комментарии

// загружаю комментарии…

Комментарии публикуются после проверки. Ссылки и HTML не принимаются.