From 097fb4d81926cab69f1455732e77cebfa43d742d Mon Sep 17 00:00:00 2001 From: Jose Diaz-Gonzalez Date: Sun, 22 Sep 2024 21:02:20 -0400 Subject: [PATCH] feat: clear out docker builder cache once a day There have been a number of tickets in the past - most recently #7061 - covering the fact that Dokku doesn't clean up disk utilization. The underlying issue is that Docker uses build cache that cannot be cleaned up in a targeted way - and usually doesn't even respect the builder gc settings in a way that makes sense. In fact, the computed disk space does not line up with actual disk utilization, causing it to be a mystery to anyone investigating the underlying problem. This change introduces a cron-based mechanism that cleans up disk once a day. Cleaning up more often would potentially cause issues during a build if for some reason the prune and an app deploy happened at the same time - its not clear if there is a lock on build cache usage - so cleaning up after hours once a day is a decent tradeoff. In the future, this setting may be modifiable, but it works well for now. Closes #7061 --- docker/etc/cron.d/docker-builder-prune | 4 ++ plugins/builder/install-builder-prune | 51 ++++++++++++++++++++++++++ plugins/builder/triggers.go | 6 ++- 3 files changed, 60 insertions(+), 1 deletion(-) create mode 100644 docker/etc/cron.d/docker-builder-prune create mode 100755 plugins/builder/install-builder-prune diff --git a/docker/etc/cron.d/docker-builder-prune b/docker/etc/cron.d/docker-builder-prune new file mode 100644 index 000000000..dcdafe459 --- /dev/null +++ b/docker/etc/cron.d/docker-builder-prune @@ -0,0 +1,4 @@ +PATH=/usr/local/bin:/usr/bin:/bin +SHELL=/bin/bash + +5 4 * * * root /usr/local/bin/docker builder prune >>/var/log/dokku/builder-prune.log 2>&1 diff --git a/plugins/builder/install-builder-prune b/plugins/builder/install-builder-prune new file mode 100755 index 000000000..c61e945c4 --- /dev/null +++ b/plugins/builder/install-builder-prune @@ -0,0 +1,51 @@ +#!/usr/bin/env bash +set -eo pipefail +[[ $DOKKU_TRACE ]] && set -x + +trigger-builder-install-prune() { + declare desc="builder install plugin trigger" + declare trigger="install" + + if [[ $(systemctl 2>/dev/null) =~ -\.mount ]]; then + cat </etc/systemd/system/docker-builder-prune.service +[Unit] +Description=Docker builder prune service +Requires=docker.service +After=docker.service + +[Service] +Type=oneshot +User=$DOKKU_SYSTEM_USER +ExecStart=$DOCKER_BIN builder prune + +[Install] +WantedBy=docker.service +EOF + + cat </etc/systemd/system/docker-builder-prune.timer +[Unit] +Description=Run docker-builder-prune.service every day at 4:05am + +[Timer] +OnCalendar=Mon..Sun 04:05 +Persistent=true + +[Install] +WantedBy=timers.target +EOF + if command -v systemctl &>/dev/null; then + systemctl --quiet reenable docker-builder-prune + systemctl --quiet enable docker-builder-prune.timer + systemctl --quiet start docker-builder-prune.timer + fi + else + cat </etc/cron.d/docker-builder-prune +PATH=/usr/local/bin:/usr/bin:/bin +SHELL=/bin/bash + +5 4 * * * $DOKKU_SYSTEM_USER $DOCKER_BIN builder prune >>/var/log/dokku/builder-prune.log 2>&1 +EOF + fi +} + +trigger-builder-install-prune "$@" diff --git a/plugins/builder/triggers.go b/plugins/builder/triggers.go index 37f2821c5..50e380994 100644 --- a/plugins/builder/triggers.go +++ b/plugins/builder/triggers.go @@ -99,7 +99,11 @@ func TriggerInstall() error { return fmt.Errorf("Unable to install the builder plugin: %s", err.Error()) } - return nil + _, err := common.CallPlugnTrigger(common.PlugnTriggerInput{ + Trigger: "install-builder-prune", + }) + + return err } // TriggerPostAppCloneSetup creates new builder files