An image whose /etc/logrotate.d/mail is group-writable makes logrotate ignore the file, so mail.log never rotates and grows until the volume does. The file is 0644 in git and is widened on the way into the build context: COPY takes the mode it finds, and an archive made from a checkout without POSIX permissions carries the umask-widened one. Measured at 0644, 0664 and 0666 across three images built on one host from the same commit range. Written up rather than patched because three things are wrong and fixing the visible one hides the rest: every COPY in the image trusts the build context, logrotate exits 0 while ignoring the file so the rotate loop reports success, and nothing anywhere notices that a rotation did not happen. Whether the release workflow's own images are affected is stated as unverified — the published image could not be pulled to check. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
4.0 KiB
Plan: logrotate-mode (mail.log stops rotating in some images)
Status: candidate
Version: patch; no schema, no configuration surface.
Order: independent. Worth doing before anything that lets an instance run
unattended for months.
What was observed
The container log carries, on every start:
warning: Potentially dangerous mode on /etc/logrotate.d/mail: 0664
error: Ignoring /etc/logrotate.d/mail because it is writable by group or others.
logrotate refuses a configuration file that group or others may write, so
mail.log is never rotated in an image with that mode. It grows until the
volume does.
Measured across three images built on the same host from the same commit range:
| Image built from | Mode of /etc/logrotate.d/mail |
|---|---|
| a sync made two days earlier | 0644 — works |
a later sync (tar -czf - pipe from a Windows checkout) |
0666 |
a later sync (git archive from the same checkout) |
0664 |
So the file is fine in the repository (git records 100644) and is spoiled on
the way into the build context. COPY build/logrotate-mail.conf /etc/logrotate.d/mail (build/Dockerfile) takes the
mode from the context as it finds it, and an archive produced from a checkout
without POSIX permissions carries the umask-widened mode instead of the one git
recorded.
Not established: whether images built by the release workflow are affected.
They are built from a checkout on Linux, where the mode should survive as
0644, but the published image could not be pulled to check. Confirm before
concluding that only locally built images have this.
Why it deserves a plan rather than a one-line fix
Three separate things are wrong, and fixing only the visible one leaves the other two.
- The image trusts the build context's file modes. Every
COPYin the Dockerfile has this property, not just this one; the scripts happen to bechmod +x-ed afterwards, which is why they were never noticed. - The failure is silent.
logrotate-loop.shrunslogrotate /etc/logrotate.d/mailand only reports a failure on a non-zero exit — but logrotate ignores the file and exits 0, so the loop reports nothing and the operator's only clue is a warning printed once at start. - Nothing checks the outcome. No test or health check notices that
mail.loghas not rotated, and the panel's Status page has no view of it.
Directions to weigh
COPY --chmod=0644on the configuration files (and an explicit mode on the scripts instead of the laterchmod +x), which makes the image's file modes a property of the Dockerfile rather than of whoever built it. Needs a check of the minimum BuildKit version the project is willing to require.- Or an explicit
chmodin the sameRUNthat already fixes the scripts — cruder, no build-time requirement. - Make
logrotate-loop.shfail loudly:logrotatehas--debug-free ways to be told to care, but the simplest reliable check is that the loop verifies the configuration is readable-and-not-writable before entering the loop, and exits non-zero so supervisord reports it. - Consider whether the e2e stack should assert that a rotation actually happens
(it can run with a short
LOGROTATE_INTERVAL_SECONDS).
Done when
- An image built from a Windows checkout and one built by the release workflow
both carry
0644, and rotation runs in both. - A configuration logrotate would ignore makes the container say so in a way an operator will see, rather than exiting 0.
- The dev loop's sync step cannot silently widen file modes again, or the image no longer cares if it does.
Risks
- Low blast radius, but it touches the image's startup path — a mistake here is a container that will not start rather than a log that does not rotate.
- The
create 0640 postfix selfpostline in the rotate configuration is load bearing (see the comment inlogrotate-loop.sh: a postlogd-triggered recreate lands the file unreadable by the unprivileged panel). Any rework of the configuration must keep it.