Automatické čištění Docker cache volumes pro Gitlab Runner

Jak vyřešit problém s neustále rostoucími Docker volumes pro GitLab Runner cache a nastavit jejich automatické čištění.

Problém

GitLab Runner při použití Docker executoru vytváří volumes pro ukládání cache mezi buildy. Tyto volumes však nemají žádný vestavěný mechanismus pro automatické čištění a postupem času mohou narůst do obřích rozměrů – není výjimkou vidět stovky gigabajtů či dokonce terabajty obsazeného místa.

Volumes můžete zobrazit příkazem:

docker volume ls | grep runner

A jejich velikost zjistíte pomocí:

for vol in $(docker volume ls -q | grep -E '^runner-.*-cache'); do
    SIZE=$(docker run --rm -v "$vol":/data alpine du -sh /data 2>/dev/null | cut -f1)
    echo "$SIZE    $vol"
done

Typický výstup může vypadat následovně:

132G    runner-yd6eca4h-project-100-concurrent-0-cache-3c3f060a0374fc8bc39395164f415a70
124G    runner-88bmy4dg2-project-100-concurrent-0-cache-3c3f060a0374fc8bc39395164f415a70
29G     runner-0558e6a41bfb19b22a086fc2330d186c-cache-3c3f060a0374fc8bc39395164f415a70

Všimněte si dvou různých formátů pojmenování – starší verze GitLab Runneru (před 15.x) používaly 32-znakový hash, novější verze používají formát runner-{system_id}-project-{id}-concurrent-{n}.

Příčina

GitLab Runner vytváří nové cache volumes při:

  • změně cache:key v .gitlab-ci.yml
  • přeregistraci runneru (nové system_id)
  • změně projektu nebo větve (záleží na konfiguraci cache key)

Staré volumes však zůstávají na disku a nejsou automaticky mazány. Navíc při přeregistraci runneru vznikne nové system_id a všechny předchozí volumes se stanou "osiřelými".

Aktuální system_id vašeho runneru zjistíte příkazem:

cat /etc/gitlab-runner/.runner_system_id

Řešení

Jednorázové vyčištění

GitLab Runner obsahuje oficiální skript pro vyčištění cache. Na Debian/Ubuntu je součástí balíčku gitlab-runner a najdete jej v /usr/share/gitlab-runner/clear-docker-cache.

/usr/share/gitlab-runner/clear-docker-cache

Skript nabízí několik možností:

# Zobrazí nápovědu
/usr/share/gitlab-runner/clear-docker-cache help

# Smaže pouze osiřelé volumes (výchozí)
/usr/share/gitlab-runner/clear-docker-cache prune-volumes

# Smaže všechny runner cache volumes
/usr/share/gitlab-runner/clear-docker-cache space

Oficiální skript obsahuje workaround pro změnu chování v Docker 23.0, který uměle snižuje API verzi na 1.41. U novějších verzí Dockeru (API 1.44+) to způsobuje chybu, např.:

Error response from daemon: client version 1.41 is too old. Minimum supported API version is 1.44

V takovém případě použijte přímo Docker příkazy:

# Smaže volumes s GitLab Runner labelem
docker volume prune -f --filter "label=com.gitlab.gitlab-runner.managed=true"

Pro ruční smazání všech cache volumes:

docker volume ls -q | grep -E '^runner-.*-cache' | xargs -r docker volume rm

Automatické čištění pomocí cron

Pro pravidelné čištění vytvořte soubor /etc/cron.d/gitlab-runner-cache-cleanup:

# Každou neděli ve 3:00 smaže nepoužívané runner cache volumes
0 3 * * 0 root docker volume prune -f --filter "label=com.gitlab.gitlab-runner.managed=true" >> /var/log/gitlab-runner-cache-cleanup.log 2>&1

Prevence

Pro omezení růstu cache přímo v projektech lze v .gitlab-ci.yml nastavit expiraci:

cache:
  key:
    files:
      - package-lock.json  # nová cache pouze při změně dependencies
  paths:
    - node_modules/
  expire_in: 1 week

Nastavení expire_in však funguje pouze na úrovni GitLab serveru, ne na úrovni Docker volumes. Pro skutečné omezení velikosti na úrovni runneru je nutné použít výše popsané čištění.

Další zdroje

nám. Republiky 28
301 00 Plzeň
Česká republika
IČ: 28006402
DIČ: CZ28006402

© 2002 - 2025 iD-SIGN BRANDS MENTIONED ABOVE ARE PROPERTY OF THEIR RESPECTIVE OWNER.