Files
werkator/docs/prs/2026-08-10-PR#000-nightly-docker-prune-timer.md
T
mhoennigandClaude Fable 5 e1f3f5f384 Install a nightly Docker cleanup timer with init --systemd (v0.9.7)
Port of the legacy host's docker-prune.timer: 02:00 host time,
Persistent=true, docker system prune -af — but without --volumes, so
the per-repository Gradle cache volumes survive. The units are
host-global; several GitTally instances share one timer.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-10 19:22:44 +02:00

3.4 KiB

WARNING: This document describes only the change applied in this PR. It may already be outdated once the next PR is merged. Historic PR-documentation is not maintained along with new PRs — treat it as a snapshot, not as current documentation.

The Problem

The legacy host (vm2176) had a docker-prune.timer that cleaned up Docker every night at 02:00, before the nightly runs. Without it, unused images and stopped containers accumulate on the build host until the disk fills up. The rewrite did not port this timer, and it had to be installed by hand.

Non-Goals

  • No volume pruning: the legacy docker system prune -af --volumes would delete GitTally's per-repository Gradle cache volumes every night; the new cleanup keeps volumes.
  • No configurable schedule; 02:00 host time is hardcoded like on the legacy host.
  • No pruning from within the GitTally server process — the cleanup stays a plain systemd timer.

The Scenarios

Feature: nightly Docker cleanup installed with the service

Background

  • The legacy unit (vm2176, Hostsharing-internal) ran docker system prune -af --volumes at 02:00 with Persistent=true.
  • GitTally's Docker builds maintain a per-repository Gradle cache volume that must survive a cleanup.

Scenario#000.01: init --systemd generates the cleanup units alongside the service unit

So that the cleanup is part of every GitTally installation instead of a manual step.

  • Given a repository initialized with init --systemd
  • When the generation finishes
  • Then .git/gittally/gittally-docker-prune.service and .git/gittally/gittally-docker-prune.timer exist
    • and the printed install commands link and enable the timer together with the service
Verified by

Scenario#000.02: The cleanup prunes containers and images but never volumes

So that nightly builds start from fresh images while the Gradle caches survive.

  • Given the generated gittally-docker-prune.service
  • When the timer fires at 02:00 host time
  • Then it runs docker system prune -af (stopped containers, unused images, networks, dangling build cache)
    • and it passes no --volumes flag
    • and on hosts without a docker CLI the run is skipped, not failed
Verified by

The Solution

SystemdServiceFiles gets pruneServiceContent()/pruneTimerContent() next to the existing unit generation, and createSystemdFiles writes both files and extends the printed install commands. The unit names are host-global (gittally-docker-prune.*, no repository name): Docker is a host-wide resource, so several GitTally instances on one host share one timer — every init --systemd regenerates the same content and the symlinks coincide. Running containers and their images are never pruned by Docker, so an in-flight build is safe even if it overlaps 02:00. Documented in docs/deployment.md (section "Nightly Docker Cleanup").

Additional Changes

  • None.

Follow-up PRs

  • None planned.