Files
admin/.wiki/concepts/registry-gc-mount-and-modify-flag.md

4.9 KiB
Raw Blame History

title, type, tags, sources, updated
title type tags sources updated
Docker Registry garbage-collect mount layout + `-m` flag concept
docker-registry
garbage-collect
gotcha
storage
../sources/vds-kzntsv-bootstrap-2026-05-20.md
2026-05-20

Registry GC — mount path и -m flag

Распознаваемая пара ошибок при registry garbage-collect на offline-restored backup data. Один shoot — -m flag для реального удаления, второй — правильный mount path.

Симптом 1 — Path not found: /docker/registry/v2/repositories

Запуск:

docker run --rm \
  -v /volume1/docker/infrastucture/registry/docker:/var/lib/registry \
  registry:2.8.3 garbage-collect /etc/docker/registry/config.yml

Ошибка: failed to garbage collect: failed to mark: filesystem: Path not found: /docker/registry/v2/repositories.

Root cause

Default config файл /etc/docker/registry/config.yml в registry image имеет:

storage:
  filesystem:
    rootdirectory: /var/lib/registry

Registry expect'ит файлы в /var/lib/registry/docker/registry/v2/.... Mounting только docker/ subdir host'а к /var/lib/registry/ положит данные в /var/lib/registry/registry/v2/... (один уровень потерян).

Fix — mount PARENT directory

docker run --rm \
  -v /volume1/docker/infrastucture/registry:/var/lib/registry \   # <-- parent dir, не /docker
  registry:2.8.3 garbage-collect /etc/docker/registry/config.yml

Теперь internal path = /var/lib/registry/docker/registry/v2/... .

(Original kreknin compose использовал ./:/var/lib/registry — mount whole registry parent dir — что было корректно но для running registry, не для offline GC.)

Симптом 2 — GC ничего не удаляет, размер прежний

После первого GC прохода видим лог:

blob eligible for deletion: sha256:087b41...
time="..." level=info msg="Deleting blob: /docker/registry/v2/blobs/sha256/08/087b41..."

Лог говорит «Deleting» — но du -sh показывает прежний 99G. Размер не изменился.

Root cause

registry garbage-collect без флагов работает в dry-run mode (incident-free). Лог «Deleting blob» — info level намерения, не actual unlink.

Подобный intent vs action разделение типично для batch tools (apt-get -s, git rm --dry-run, etc.) но в registry CLI нет attention-grabbing --dry-run flag — а опция «реально делать» named cryptically.

Fix — -m (modify) flag

docker run --rm \
  -v /volume1/docker/infrastucture/registry:/var/lib/registry \
  registry:2.8.3 garbage-collect -m /etc/docker/registry/config.yml

С -m после прохода размер реально уменьшается. На kreknin backup'е: 99G → 35G (64G freed), 2-3 минуты обработки.

Полный рецепт offline GC restored backup data

# 1. Pull registry image что соответствует production версии (compatibility)
docker pull registry:2.8.3

# 2. (Optional) dry-run для отчёта — что будет удалено
docker run --rm \
  -v /path/to/restored/registry:/var/lib/registry \
  registry:2.8.3 garbage-collect /etc/docker/registry/config.yml \
  > gc-dry-run.log 2>&1

# 3. Реальный GC
docker run --rm \
  -v /path/to/restored/registry:/var/lib/registry \
  registry:2.8.3 garbage-collect -m /etc/docker/registry/config.yml

# 4. Measure delta
du -sh /path/to/restored/registry/docker

Online GC (production live registry) — важные дополнения

Если делаем GC на running registry — нужен read-only mode чтобы избежать race condition'ов (новый push во время GC может потерять blobs):

# Add to running registry config / env vars
storage:
  maintenance:
    readonly:
      enabled: true

Затем restart registry, run GC -m, отключить read-only, restart again. Окно downtime — продолжительность GC (~10-30 min на средних объёмах).

Где применено

vds-kzntsv Phase 3.3 — GC kreknin'овского backup'а 99G → 35G. После того как user decided abandon миграцию и fresh install — GC оказался полезной экономией если бы tar/rsync'или (но в финале rsync не запустился).

Ссылки