English · Русский — историю релизов смотрите в CHANGELOG.ru.md.
Репозиторий собирает Docker-образы, объединяющие демон FreeUnit (форк NGINX Unit) со встроенным модулем PHP, установленным из готовых Debian-пакетов.
- Апстрим FreeUnit: https://github.com/freeunitorg/freeunit
- Сборки пакетов для trixie: https://github.com/6RUN0/freeunit/releases —
форк, который организует
.deb-сборки под Debian trixie, устанавливаемые этим образом. - Дистрибутив: Debian trixie (только amd64 — апстрим публикует
.debлишь под amd64). - Версии PHP: 8.3, 8.4, 8.5 (по одному встроенному PHP на образ — встраиваемый SAPI допускает только один).
Единый параметризованный Dockerfile покрывает всю матрицу через build-args;
Makefile собирает каждый вариант.
Готовые образы публикуются в GitHub Container Registry по адресу
ghcr.io/6run0/freeunit-php. Каждый релиз публикует по одному образу на каждую
ветку PHP (8.3 / 8.4 / 8.5) под несколькими тегами, чтобы можно было закрепиться
настолько свободно или строго, насколько нужно:
| Шаблон тега | Пример | Указывает на |
|---|---|---|
latest |
ghcr.io/6run0/freeunit-php |
свежий релиз, PHP по умолчанию (8.4) |
<версия> |
:0.1.0 |
этот релиз репозитория, PHP по умолчанию |
<suite>-php<X.Y> |
:trixie-php8.3 |
свежий релиз на ветке PHP (двигается вперёд) |
<версия>-php<X.Y> |
:0.1.0-php8.3 |
релиз репозитория на ветке PHP |
<suite>-<релиз-freeunit>-php<X.Y> |
:trixie-1.35.5-build4-php8.5 |
конкретная сборка FreeUnit на ветке PHP |
docker pull ghcr.io/6run0/freeunit-php:trixie-php8.4Теги latest и <suite>-php<X.Y> плавающие — следующий релиз перенаправляет
их. Теги <версия>… и …-<релиз-freeunit>… остаются привязанными к одному
релизу. Для байт-стабильного деплоя закрепляйтесь по дайджесту (…@sha256:…) —
именно эту форму проверяет и gh attestation verify (см. раздел
«Примечания»).
# Образ по умолчанию (trixie, php8.4)
docker build -t freeunit-php .
# Конкретная версия PHP
docker build --build-arg PHP_VER=8.3 -t freeunit-php:8.3 .
# Зафиксировать другой релиз FreeUnit
docker build \
--build-arg FREEUNIT_VERSION=1.35.5-1 \
--build-arg FREEUNIT_RELEASE=1.35.5-build4 \
-t freeunit-php .Или через Makefile:
make # собрать все версии PHP (8.3, 8.4, 8.5)
make php8.3 # собрать один вариант
make latest # собрать PHP по умолчанию (8.4) и пометить тегом :latest
make test # собрать PHP по умолчанию и прогнать интеграционный smoke-тест
make lint # запустить все установленные линтеры (hadolint, shellcheck, rumdl, typos)
make scan # CVE-сканирование образа по умолчанию (trivy/grype, если установлены)Значения по умолчанию для конкретного релиза (SUITE, PHP_VER,
FREEUNIT_VERSION, FREEUNIT_RELEASE) хранятся в ARG-ах Dockerfile, а
Makefile читает их оттуда, поэтому смена версии — это одна правка в
Dockerfile. Любую переменную можно переопределить в командной строке,
например make FREEUNIT_RELEASE=1.35.6-build1 FREEUNIT_VERSION=1.35.6-1.
docker run -d --name app \
-p 8080:8080 \
-v "$PWD/www:/www:ro" \
-v "$PWD/config.json:/docker-entrypoint.d/config.json:ro" \
freeunit-phpПри первом запуске (когда /var/lib/freeunit пуст) entrypoint поднимает демон на
управляющем сокете, применяет всё содержимое /docker-entrypoint.d/, а затем
перезапускает демон на переднем плане. Если эта первоначальная настройка не
удалась, каталог состояния очищается, чтобы следующий запуск начался с чистого
листа.
Запускаемые примеры лежат в examples/, по одному на подкаталог:
examples/basic/— самодостаточный, ужесточённый по безопасности деплой (маленькийDockerfileзапекает приложение и его конфиг в образ):cd examples/basic && docker compose up --build.examples/cron-hook/— система хуков entrypoint: один образ работает в двух ролях, веб-сервер Unit и долгоживущий cron-раннерsupercronic, выбираемых для каждого контейнера командой, без второго образа и без переопределения entrypoint.
Файлы применяются в лексическом порядке, по расширению:
| Расширение | Действие |
|---|---|
*.sh |
Исполняется (от root). |
*.pem |
Загружается как набор сертификатов с именем файла (без .pem). |
*.json |
Отправляется PUT-запросом в config Unit через управляющий сокет. |
Файлы прочих типов логируются и игнорируются.
Несколько
*.jsonне объединяются:PUT /configзаменяет всю конфигурацию, поэтому в силу вступает только лексически последний файл (entrypoint предупреждает, если их больше одного). Поставляйте один объединённый файл конфигурации.
Это runtime-API образа; их читает entrypoint.
| Переменная | По умолчанию | Назначение |
|---|---|---|
APPLICATION_USER |
freeunit |
Пользователь приложения. Если уже существует, его UID сохраняется. |
APPLICATION_UID |
1000 |
UID, используемый только при создании пользователя. |
APPLICATION_GROUP |
freeunit |
Группа приложения. Если уже существует, её GID сохраняется. |
APPLICATION_GID |
1000 |
GID, используемый только при создании группы. |
APPLICATION_DIR |
не задана | Домашний каталог приложения; создаётся, если отсутствует. |
APPLICATION_CHOWN |
yes |
При yes выполняет chown APPLICATION_DIR на пользователя приложения. |
UNIT_ENTRYPOINT_QUIET_LOGS |
не задана | Если задана, отключает логи entrypoint. |
APPLICATION_DIRдолжен указывать на путь, принадлежащий контейнеру. ПриAPPLICATION_CHOWN=yesего владелец переписывается, поэтому указание на host-bind-mount перепишет владельца файлов на хосте.
Мастер-процесс Unit работает от root по своей природе — он привязывается к
привилегированным портам и порождает воркеры на каждое приложение. Сбрасывайте
привилегии для приложения через ключи user/group в конфиге Unit (а не
сменой пользователя контейнера) и ужесточайте контейнер в рантайме:
docker run --cap-drop=ALL --cap-add=SETUID --cap-add=SETGID \
--security-opt=no-new-privileges ... freeunit-phpОтноситесь к /docker-entrypoint.d/*.sh как к доверенному вводу — эти скрипты
исполняются от root внутри контейнера.
-
Только amd64. FreeUnit публикует
.debпод amd64; сборкиlinux/arm64нет. -
Плавающая основа. Образ фиксирует релиз FreeUnit, но база Debian и пакеты PHP с deb.sury.org — rolling, а на этапе сборки выполняется
apt full-upgrade, поэтому две сборки одного тега не бит-в-бит воспроизводимы. -
Проверка целостности
.deb— это сверка SHA256 с собственнымSHA256SUMSрелиза, который сам закреплён в репозитории по своему дайджесту, поэтому подменённый релиз не сможет подсунуть подходящий файл контрольных сумм (целостность, не апстрим-подлинность — подписи FreeUnit нет). -
Публикуемые образы несут аттестации. Каждый образ, отправленный в GHCR релизным воркфлоу, записывает безключевую аттестацию происхождения сборки и SBOM в формате SPDX как аттестации Sigstore. Проверьте скачанный образ, прежде чем доверять ему:
gh attestation verify \ oci://ghcr.io/6run0/freeunit-php@<digest> --owner 6RUN0