From d12f40c9a066d40b33f6124bd6ea708dde51e6d0 Mon Sep 17 00:00:00 2001 From: zhangwenjian Date: Wed, 9 Sep 2026 07:45:51 +0800 Subject: [PATCH] =?UTF-8?q?ci=F0=9F=91=B7:=20remove=20this=20repository's?= =?UTF-8?q?=20old=20images=20after=20a=20healthy=20deploy?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Every deployment pulls an image tagged with its commit and nothing removed the previous one, so they only accumulated. 68 had built up when a deployment failed on a pull with no space left on the device. That is the harmless place to fail - the site kept serving the image it already had - but no later run would have recovered on its own. Three are kept so a release can be re-run by tag by hand. Only this repository's images are listed, because the host runs other services. The image the new container is on is excluded by id rather than by position, and rmi is called without -f so an image a container still holds is refused rather than taken from it. Verified against a real docker daemon: with five images newer than the running one, so position alone no longer protects it, the pipeline leaves three and does not select the live one. Removing the id exclusion from the same pipeline does select it, so that guard is load-bearing rather than decorative. --- .github/workflows/build.yml | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 94cd4cea..33c9a8f3 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -155,6 +155,31 @@ jobs: if [ "$ok" = "1" ]; then sudo docker rm -f "$PREV" >/dev/null 2>&1 || true + + # Old images of this repository are deleted here and nowhere + # else. Every deployment pulls one image tagged with its commit + # and nothing ever removed the previous one, so they only ever + # accumulated: 68 of them filled the disk and the next deployment + # could not pull. That one stopped at the pull, which + # is the harmless place to stop - the site kept serving the image + # it already had - but no later run would have recovered either. + # + # Three are kept so a release can be re-run by tag by hand. + # + # Only this repository's images are listed: the host runs other + # services whose images are not this script's business. The image + # the new container is on is excluded by id rather than by + # position, so it survives even if the listing order is not what + # it looks like. No -f, so an image some container still holds is + # refused rather than taken away from it, and a refusal does not + # fail a deployment that has already succeeded. + REPO="${IMG%:*}" + LIVE=$(sudo docker inspect -f '{{.Image}}' "$NAME" | sed 's/^sha256://' | cut -c1-12) + sudo docker images "$REPO" --format '{{.ID}} {{.Repository}}:{{.Tag}}' \ + | grep -v "^$LIVE" \ + | tail -n +3 \ + | awk '{print $2}' \ + | xargs -r -n1 sudo docker rmi >/dev/null 2>&1 || true else echo "健康检查失败,回滚到上一版本" sudo docker logs --tail 40 "$NAME" 2>&1 || true