Правила очистки GitLab container registry, которые сохраняют нужные теги
Правила очистки GitLab container registry помогают удалить старые CI-образы, сократить лишний расход места и сохранить теги, которые нужны для отката и проверки инцидентов.

Почему реестр постоянно растет
Обычно реестр GitLab становится больше тихо и незаметно. Каждая сборка ветки, merge request и коммит может отправлять новый образ, даже если никто не собирается использовать его снова. CI идет дальше, а реестр хранит все, если вы сами не скажете ему не делать этого.
Из этого получается знакомая картина. Новые теги появляются каждый день. Старые теги остаются навсегда. Команды помечают образы именами веток, короткими хешами коммитов, release candidate, тегами для тестов и разовыми исправлениями. Через несколько недель реестр уже забит образами, которые относятся к работе, давно завершенной.
Объем растет даже тогда, когда приложение почти не меняется. Небольшое изменение кода все равно создает новый тег. Обновления базового образа и пересборка зависимостей со временем добавляют новые слои. Каждый push сам по себе выглядит безобидно, но сотни таких мелких push’ей превращаются в проблему хранения в container registry, которая продолжает расти.
Типичный случай выглядит просто: три разработчика пушат несколько раз в день, пайплайны собирают образы для feature-веток, staging и main, а большинство этих тегов никогда не доходит до production. Они все равно месяцами лежат в реестре, потому что никто не хочет гадать, какие из них безопасно удалить.
Осторожность здесь понятна. Откат — это стресс. Если production ломается, команде нужен известный образ, который можно быстро развернуть. Если позже появляется проблема безопасности, может понадобиться старый образ, чтобы проверить, какой код и какие зависимости в нем были. Поэтому страх берет верх, очистка откладывается, а у GitLab image retention так и не появляется внятной политики.
Большинство команд не халатны. Они просто стараются действовать аккуратно. Проблема в том, что никто не отделяет «теги, которые нам действительно нужны» от «тегов, которые CI создал и забыл». Именно эту задачу и решают правила очистки GitLab container registry. Они позволяют удалять временные образы, сохраняя теги, от которых по-прежнему зависит ваш план отката и процесс реагирования на инциденты.
Какие теги стоит сохранять
Начните с тегов, которые ваши системы используют прямо сейчас. Если сервер, кластер или customer environment все еще тянет тег, оставьте его. Удаление живого тега немного экономит место, но может создать куда большую проблему, когда нужно масштабироваться, переразвернуть приложение или заменить ноду.
Дальше идут release-теги. Это ваша страховка на случай, если свежий деплой сломается в 2 часа ночи. Если v1.14.2 — это последний удачный релиз, сохраните его, даже если CI уже собрал еще двадцать более новых образов.
Большинству команд стоит хранить больше чем одну точку отката. Хорошая базовая схема — текущий production-тег плюс небольшой набор свежих release-тегов, которым вы доверяете. Так у вас будет запас, чтобы сделать один-два шага назад, не пересобирая старый образ в спешке.
Некоторые теги важны не только для деплоя. Если команда расследует инцидент, взлом или проблему supply chain, образ, связанный с этим событием, может стать доказательством. Работа по безопасности сильно усложняется, когда точный образ уже удален и всем приходится гадать, что в нем было.
У аудита та же потребность. Если вы обещали клиенту, регулятору или внутренней команде показать, что именно работало в production в определенный день, сохраните теги образов, которые это подтверждают. Логи помогают, но логи вместе с самим образом дают более ясную картину.
Для большинства команд список сохранения остается коротким:
- тег, который сейчас использует production
- несколько свежих release-тегов для отката
- любой тег, связанный с инцидентом или проверкой безопасности
- любой тег, который может понадобиться для аудита
Небольшому стартапу не нужен огромный архив, чтобы оставаться в безопасности. Часто достаточно хранить prod, последние пять релизов по semantic version и несколько тегов, помеченных для расследования. Если тег может восстановить сервис, объяснить инцидент или доказать, что именно было выпущено, относитесь к нему как к записи, а не как к мусору.
Сделайте имена тегов предсказуемыми
Правила очистки работают только тогда, когда названия тегов говорят правду. Если команда использует имена вроде latest, test, final и prod2, никто не понимает, что можно безопасно удалить. Очистка CI-образов становится намного проще, когда у каждого тега есть одна понятная задача.
Первое разделение должно быть между временными тегами и постоянными. Сборки веток — временные. Они нужны для review apps, тестовых прогонов и коротких проверок. Release-теги — это другое дело. Они могут понадобиться снова для отката, поддержки или разбирательства через несколько недель.
Обычно хорошо работает простая схема именования:
branch-main-<sha>илиbranch-login-fix-<sha>для сборок ветокmr-142-<sha>для тестирования merge requestrelease-v1.8.2для неизменяемых релизовprod-currentдля образа, который сейчас использует productionprod-previousдля последнего удачного production-образа
Release-теги должны быть скучными. release-v1.8.2 намного лучше, чем stable-new или good-build. Когда кого-то поднимают ночью по тревоге, он должен сразу понимать, какой образ брать, без догадок.
Production-теги тоже могут быть стабильными, не становясь при этом расплывчатыми. Двигающийся тег вроде prod-current помогает и людям, и инструментам деплоя быстро находить живой образ. При этом его стоит дополнять неизменяемым release-тегом на том же образе, чтобы всегда можно было понять точную версию за этим указателем.
Команды начинают путаться, когда тестовые теги и теги для отката пересекаются. Если qa, stage или test-ok иногда указывают на эксперимент, а иногда на release candidate, правила очистки превращаются в угадайку. То же самое касается отката.
Выберите одно правило и придерживайтесь его: временные теги должны описывать, откуда пришла сборка, а сохраняемые теги — релиз или состояние деплоя. Одно это решение предотвращает большинство ошибок в очистке еще до того, как вы сохраните первое правило.
Если у вас несколько приложений, используйте одинаковую схему именования везде. Люди реже ошибаются, когда каждый проект отвечает на один и тот же вопрос одинаково: этот тег временный или он еще понадобится позже?
Как правила очистки решают, что удалять
Правила очистки GitLab container registry работают по шаблонам тегов и настройкам хранения. Они не знают, какие образы важны для вашей команды, если ваши имена тегов этого не показывают.
Когда запускается очистка, GitLab проверяет каждый тег по заданным правилам. Если сказать простыми словами, он задает четыре вопроса:
- Совпадает ли имя тега с шаблоном очистки?
- Старше ли тег установленного возрастного лимита?
- Не входит ли он в небольшой набор последних тегов, которые нужно сохранить?
- Не защищен ли он?
Только теги, которые проходят эти проверки, попадают под удаление. Поэтому имя тега так важно. Если люди пушат случайные теги, правило не сможет отличить безопасный остаток CI от образа, который может понадобиться уже на следующей неделе.
Сохранение нескольких самых новых совпадающих тегов особенно полезно для branch-, merge request- и commit-тегов. Они быстро накапливаются, но командам часто все еще нужны самые свежие версии для тестирования или отладки.
Защищенные теги обычно не попадают в стандартный путь очистки. Если команда защищает release-теги вроде v2.4.1, prod или staging-approved, GitLab их не трогает. Для большинства команд это правильное разделение: временный CI-вывод может истечь, а теги для отката и forensics остаются доступными.
Вот где это работает хорошо. Допустим, разработчики пушат образы вроде pr-182-1a2b3c для merge request, а release-образы используют v1.9.0. Правило очистки может нацелиться на шаблон pr-, сохранить последние 10 или 20 тегов и удалять более старые через несколько дней.
Проблемы начинаются, когда именование «плывет». Если люди также пушат теги вроде test, temp, final или joe-fix, правило перестает быть надежным. Хорошая очистка зависит от реальной истории тегов, а не от схемы, спрятанной в старой странице wiki.
Прежде чем что-то сохранять, посмотрите на теги, которые команда использует на самом деле. Если имена беспорядочные, сначала наведите порядок в них. Очистка становится намного безопаснее, когда каждый короткоживущий образ выглядит временным, а каждый тег для отката — постоянным.
Как настроить правило без риска для отката
Начните с тегов, к которым вы не хотите, чтобы GitLab вообще прикасался. Большинство сожалений после очистки возникают из-за удаления того единственного образа, который понадобился команде для отката, аудита или поздней проверки бага. Постоянные теги должны быть короткими, понятными и задокументированными.
Для многих команд безопасный список сохранения включает versioned releases, теги, используемые в production или staging, hotfix-теги, которые могут понадобиться снова, incident-теги и небольшое число свежих сборок с default branch.
После этого решите, сколько branch-образов люди действительно используют. Будьте честны. Команды часто говорят, что им нужны последние двадцать образов с каждой ветки, но на деле большинство из них берут только последние два-пять. Слишком большое число branch-сборок превращает реестр в склад догадок.
Feature- и test-теги должны истекать быстро. Если ветка живет несколько дней, храните эти образы несколько дней. Если ваш цикл QA длиннее, храните их неделю или две. Старые feature-теги почти никогда не получают вторую жизнь.
Release-, hotfix- и forensic-теги требуют другого подхода. Не полагайтесь для них только на возраст. Forensic-образ, которому шесть недель, все еще может быть важен, если вы разбираете проблему безопасности или доказываете, что именно работало во время инцидента. Явно исключите эти шаблоны, чтобы они переживали обычную очистку.
Простые правила обычно лучше хитрых. Защищайте постоянные теги по шаблону. Храните небольшое число свежих branch-образов. Удаляйте старые feature- или test-теги по короткому таймеру. Этого достаточно для большинства реальных сценариев, не превращая политику в нечто, чему никто не доверяет.
Представьте одно приложение, которое создает теги вроде main-451, feature-login-98, v2.3.0 и forensic-2026-04-12. Логика проста. Сохраняйте v2.3.0 и все, что начинается с forensic-. Сохраняйте несколько последних main-образов. Позвольте старым feature--тегам истекать через короткое время.
Потом внимательно посмотрите на первый запуск очистки. Сравните, что осталось, с тем, что исчезло. Если результат кажется слишком жестким, скорректируйте правила сохранения до следующего запуска. Один аккуратный просмотр в начале может сэкономить часы боли при откате позже.
Одна простая схема, которая работает
Представьте одно приложение с обычным процессом релизов. Каждый push в feature-ветку создает образ вроде feat-login-4821. Слияния в main создают теги вроде main-20260413-1030, а релизы используют понятные version-теги вроде v2.7.0.
Для такой команды удобен простой дефолт. Храните 10 самых новых образов из main, чтобы можно было быстро откатиться, если последний деплой сломает checkout или login. Десяти обычно хватает, чтобы покрыть несколько деплоев и один неудачный hotfix, не забивая реестр месячным накоплением старых сборок.
Release-теги подчиняются другому правилу. Если релиз помечен как v2.7.0 или v2.7.1, сохраните его. Эти теги отмечают реальные точки выпуска, и команде часто нужны они позже для поддержки клиентов, аудита или работы с инцидентом.
Образы feature-веток могут устаревать быстро. Большинство веток либо сливается, либо исчезает, поэтому удалять такие образы через 7 дней — разумная отправная точка. Это дает разработчикам достаточно времени, чтобы протестировать ветку, снова открыть merge request или сравнить сборки, но при этом не дает старым тегам накапливаться.
Можно также зарезервировать один префикс для работы с инцидентами, например incident-492-db-timeout. Такие образы должны оставаться до завершения разбора, даже если им больше недели. Во время аварии точный образ, использованный для исправления, может быть не менее важен, чем логи.
Практичный набор правил для такого приложения выглядит так:
- Хранить все release-теги, например
v1.4.3 - Хранить 10 самых свежих тегов, которые начинаются с
main- - Удалять теги, которые начинаются с
feat-, через 7 дней - Хранить теги, которые начинаются с
incident-, пока кто-то не удалит их вручную
Вот почему теги для отката работают лучше всего, когда их имена рассказывают понятную историю. Если каждой временной сборке дать предсказуемый префикс, GitLab сможет удалять старые образы, не трогая те, что связаны с откатом, поддержкой или инцидентами.
Одна небольшая привычка делает это безопаснее: после каждого релиза проверьте, что новый version-тег есть в реестре до запуска очистки. Это занимает меньше минуты и предотвращает ошибки, которые люди замечают только тогда, когда срочно нужен старый билд.
Ошибки, которые приводят к болезненным откатам
Самые неприятные ошибки очистки не видны в спокойные дни. Они всплывают, когда деплой ломает вход в систему в 6 вечера, а нужного образа уже нет.
Одна из самых частых ошибок — считать latest единственным тегом, который стоит хранить. Этот тег меняется при каждом push. Если плохая сборка его заменит, ваш чистый точка отката исчезнет вместе с ним. Храните теги, которые указывают на конкретную сборку, коммит или релиз. latest может оставаться, но он никогда не должен быть единственной страховкой.
Команды также слишком мало хранят историю с main-ветки. Это особенно больно для быстро меняющихся проектов. Если вы деплоите по десять или двадцать раз в день и храните только последние три main-образа, вы можете удалить последний удачный билд раньше, чем кто-то поймет, что возникла проблема.
Слишком широкие шаблоны создают другой тип хаоса. Правило, предназначенное для очистки branch-тегов, может задеть release-теги, если именование слишком размытое. Шаблон, который совпадает с любым тегом, начинающимся на v или release, может стереть образы, которые вы планировали хранить месяцами. Проверяйте шаблоны на реальных именах тегов, прежде чем сохранять правило.
Работа с безопасностью и соответствием требованиям создает еще один риск. Иногда команде нужны старые образы для разбора инцидента, цепочки аудита или проверки зависимостей. Если очистка удалит их слишком рано, вы потеряете не только место на диске. Вы потеряете доказательства.
Изменение тегов тоже может тихо сломать очистку. Команда переименовывает теги с prod-123 на stable-123 и забывает обновить правила хранения. GitLab продолжает следовать старому шаблону, а новые теги уходят в очередь на удаление.
Короткая проверка здравого смысла предотвращает большинство проблем с откатом:
- Храните фиксированные release-теги, а не только moving-теги
- Храните достаточно свежих
main-образов под ваш темп деплоев - Исключайте release- и hotfix-теги из широких шаблонов очистки
- Подгоняйте окно хранения под реальные сроки проверки безопасности
- Обновляйте правила всякий раз, когда меняются имена тегов
Если вы не можете сейчас сказать, на какой тег будете откатываться, правило слишком агрессивное.
Что проверить перед сохранением
Перед включением очистки посмотрите на теги, которые ваши production-системы используют прямо сейчас. Не на те, которые вы ожидаете. На те, которые реально работают в production. Если ваш процесс деплоя по-прежнему указывает на latest, имя ветки или другой moving-тег, очистка может удалить образ, нужный для безопасного отката.
Хорошее правило хранения держит место под контролем, не заставляя команду пересобирать старый образ во время инцидента. Пересборка звучит нормально, пока не изменились зависимости, не переехал базовый образ или старый коммит уже не дает тот же результат. Для отката и forensics важен точный образ.
Перед сохранением проверьте несколько вещей:
- Составьте список текущих production-тегов для каждого важного приложения и окружения, включая workers, cron jobs и другие отдельные образы
- Убедитесь, что можно откатиться на один релиз, взяв существующий образ, а не пересобирая его из старого кода
- Проверьте, что branch-, merge request-, test- и release-теги легко отличить друг от друга
- Сравните окно хранения с реальным календарем, включая длинные выходные, праздники и медленные циклы согласования
- Попросите кого-то вне команды сборки проверить правило
Последняя проверка часто оказывается самой полезной. Ops lead, engineering manager или fractional CTO нередко замечает риск быстрее, потому что видит, как деплой происходит на практике, а не только как он должен работать по задумке CI.
Простой пример показывает, почему это важно. Команда хранит образы main-<sha> для тестирования и release-2026-04-10 для production. Их правило очистки удаляет untagged-образы и branch-теги через пять дней, но сохраняет release-теги. Это выглядит безопасно, пока они не замечают, что один worker-сервис в production все еще тянет тег main-<sha>. Один быстрый просмотр ловит проблему до того, как очистка нанесет реальный ущерб.
Если вы не можете ответить на эти проверки уверенным «да», подождите. Ужесточить хранение легко. Восстанавливать удаленный образ для отката — нет.
Следите за первой неделей особенно внимательно
Когда очистка начинает работать, первая неделя говорит очень многое. Следите за объемом каждый день, но не оценивайте правило только по сэкономленному месту. После каждого деплоя задавайте один практический вопрос: если production сломается сегодня ночью, есть ли у нас все еще тот тег образа, которому мы доверяем для отката?
Меньший счет за реестр — это приятно. Безопасный откат важнее. Если инженеры начинают вручную сохранять лишние теги, потому что не доверяют правилу, политика слишком жесткая или схема именования все еще слишком размытая.
Используйте реальную историю деплоев, чтобы настроить окно. Команды часто ошибаются. Они думают, что им нужны только последние несколько образов, а потом hotfix или запрос от клиента отправляет их назад к сборке двухнедельной давности.
Если ваше приложение деплоится из main много раз в день, но откаты почти всегда используют release-теги из последних двух еженедельных релизов, храните release-теги дольше, а short-lived CI-теги удаляйте быстрее. Если никто никогда не откатывался на образ feature-ветки после merge, избавляйтесь от них раньше.
После первой недели пересмотрите несколько базовых вещей:
- Снизился ли объем хранилища настолько, чтобы оправдать правило?
- Нужен ли был какой-то образ для деплоя, отката или разбора инцидента, а очистка его уже удалила?
- Легко ли по-прежнему найти release- и hotfix-теги?
- Не придумывают ли люди ручные keep-теги, потому что система не соответствует реальной работе?
Затем запишите план тегов простыми словами. Старайтесь, чтобы он был коротким. Опишите, какие теги остаются, какие истекают, как долго живут hotfix-образы и кто может создавать постоянные теги. Новые члены команды будут следовать короткому письменному правилу намного чаще, чем старому сообщению в чате.
Не меняйте все сразу. Измените один параметр хранения, подождите несколько дней и посмотрите, что произойдет. Небольшим изменениям легче доверять, и по ним проще заметить ошибку.
Если ваша настройка GitLab, процесс релизов или политика хранения все еще кажутся запутанными, Олег Сотников на oleg.is предлагает помощь в формате Fractional CTO и advisory для стартапов, которые наводят порядок в CI/CD, инфраструктуре и безопасных практиках отката. Иногда внешний взгляд — самый быстрый способ сократить лишнее место, не создавая новый риск.