Files
werkator/docs/prs/2026-08-10-PR#000-nightly-docker-prune-timer.md
T
mhoennigandClaude Opus 5 e21c94d0e7 Retarget the links in the historic PR-docs
The package rename moved every file the older PR-docs link to, leaving
60 dead links. Only the link targets are rewritten, never the visible
text and never a statement: those documents record what was true when
they were written, GitTally in the prose included. A snapshot may be
outdated; it should still be navigable.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-31 07:34:39 +02:00

68 lines
3.4 KiB
Markdown

> **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
- [InitCommandTest — "--systemd also generates the nightly Docker cleanup timer"](../../src/test/kotlin/de/hoennig/werkator/commands/InitCommandTest.kt)
#### 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
- [SystemdServiceFilesTest — "prune service cleans containers and images but never volumes"](../../src/test/kotlin/de/hoennig/werkator/commands/SystemdServiceFilesTest.kt)
- [SystemdServiceFilesTest — "prune timer fires nightly at 02:00 and catches up after downtime"](../../src/test/kotlin/de/hoennig/werkator/commands/SystemdServiceFilesTest.kt)
## 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.