Відтворюване збирання - з того самого вихідного коду завжди виходить побітово однаковий образ (той самий дайджест), незалежно від того, коли й на якій машині його зібрали.
Навіщо:
- перевірка ланцюжка постачання: незалежне повторне збирання має дати той самий дайджест - так можна переконатися, що образ у реєстрі справді зібраний з цього коду, а не підмінений;
- кешування й дедуплікація: однаковий вміст - однаковий дайджест, не потрібно повторно завантажувати;
- налагодження: відтворити точно той образ, що працює в продакшені.
Що робить збирання невідтворюваним:
1. Мітки часу. Кожен файл у шарі має час зміни, а метадані образу - час створення. Два збирання з різницею в хвилину - різні дайджести.
Рішення - змінна SOURCE_DATE_EPOCH, яку BuildKit використовує як фіксований час (зазвичай - час останнього коміту):
SOURCE_DATE_EPOCH=$(git log -1 --format=%ct) \
docker buildx build --output type=image,name=ghcr.io/acme/app:1.4.2,push=true,rewrite-timestamp=true .
rewrite-timestamp=true переписує й мітки часу файлів у шарах.
2. Плаваючі залежності:
- базові образи без зафіксованого дайджесту;
apt-get install/apk addбез версій - пакетні репозиторії змінюються щодня;composer install/npm installбез lock-файлів (абоnpm installзамістьnpm ci);- завантаження «останньої версії» інструментів через
curl.
3. Недетермінованість інструментів: генерація випадкових значень під час збирання, порядок файлів в архівах, вбудовані дати збирання у фронтенд-бандлі чи версійні файли.
4. Середовище збирання: різні версії BuildKit можуть по-різному формувати шари.
Реалістичний рівень для більшості проєктів:
- фіксувати все, що визначає вміст (базові образи за дайджестом, lock-файли, версії інструментів);
- фіксувати час (
SOURCE_DATE_EPOCH); - збирати лише в CI з однаковим збирачем.
Повна побітова відтворюваність образів з пакетами Debian чи Alpine складна (пакетні репозиторії не зберігають старих версій вічно), тож часто достатньо «функціональної» відтворюваності: та сама поведінка, ті самі версії компонентів, задокументовані в SBOM і provenance-атестації.
Зв'язок з атестаціями: provenance фіксує, з якого коміту й з якими параметрами зібрано образ, - навіть якщо побітової відтворюваності немає, походження перевірюване.
Докладніше в документації: Відтворювані збирання з GitHub Actions