chore(ci): add automatic Docker image cleanup after builds
CI/CD Pipeline / Validate Code Quality And Tests (push) Has been cancelled
CI/CD Pipeline / Frontend Lint (push) Has been cancelled
Deploy / Deploy Staging (push) Has been cancelled
Deploy / Build Production Runtime Images (push) Has been cancelled
Deploy / Deploy Production (push) Has been cancelled
Deploy / Production Browser E2E (push) Has been cancelled
CI/CD Pipeline / Validate Code Quality And Tests (push) Has been cancelled
CI/CD Pipeline / Frontend Lint (push) Has been cancelled
Deploy / Deploy Staging (push) Has been cancelled
Deploy / Build Production Runtime Images (push) Has been cancelled
Deploy / Deploy Production (push) Has been cancelled
Deploy / Production Browser E2E (push) Has been cancelled
- Add scripts/cleanup_old_images.sh: keeps only last 2 versions per service (api/worker/web), removes old local tags and registry blobs via Registry API, prunes dangling images - Add cleanup step to deploy.yml build-production-runtime-images job with if:always() to ensure cleanup runs even on build failure - Prevents disk space exhaustion from accumulated Docker images and Registry blobs on the build server
This commit is contained in:
Executable
+63
@@ -0,0 +1,63 @@
|
||||
#!/bin/sh
|
||||
# cleanup_old_images.sh
|
||||
# 清理构建服务器上的旧 Docker 镜像和 Registry 旧版本
|
||||
# 保留最近 KEEP_VERSIONS 个版本(默认 2)
|
||||
# 在 CI 构建完成后调用,防止磁盘空间耗尽
|
||||
set -eu
|
||||
|
||||
KEEP_VERSIONS="${KEEP_VERSIONS:-2}"
|
||||
REGISTRY_HOST="${REGISTRY_HOST:-172.30.18.198:5000}"
|
||||
SERVICES="xiaoxia-saas-api xiaoxia-saas-worker xiaoxia-saas-web"
|
||||
|
||||
echo "=== Docker Image Cleanup ==="
|
||||
echo "Keeping last ${KEEP_VERSIONS} versions per service"
|
||||
echo ""
|
||||
|
||||
for svc in $SERVICES; do
|
||||
# 收集所有 v0.N.N 格式的版本号(去重,按版本号排序)
|
||||
versions=$(docker images --format "{{.Repository}}:{{.Tag}}" | \
|
||||
grep "${svc}" | \
|
||||
grep -E "v[0-9]+\.[0-9]+\.[0-9]+" | \
|
||||
sed -E "s/.*:${svc}:(v[0-9]+\.[0-9]+\.[0-9]+).*/\1/" | \
|
||||
sed -E "s/.*:v([0-9]+\.[0-9]+\.[0-9]+).*/v\1/" | \
|
||||
sort -t. -k1,1V -k2,2n -k3,3n | \
|
||||
uniq)
|
||||
|
||||
total=$(echo "$versions" | grep -c "^v" || true)
|
||||
|
||||
if [ "$total" -gt "$KEEP_VERSIONS" ]; then
|
||||
remove_count=$((total - KEEP_VERSIONS))
|
||||
to_remove=$(echo "$versions" | head -n "$remove_count")
|
||||
|
||||
echo "[Registry] Cleaning old blobs for ${svc}..."
|
||||
for ver in $to_remove; do
|
||||
repo_name=$(echo "$svc" | sed "s/xiaoxia-saas-//")
|
||||
manifest_url="http://admin:Xiaoxia2026@localhost:5000/v2/${repo_name}/manifests/${ver}"
|
||||
digest=$(curl -sI -H "Accept: application/vnd.docker.distribution.manifest.v2+json" "$manifest_url" | grep -i "^docker-content-digest:" | tr -d "\r" | awk "{print \$2}")
|
||||
if [ -n "$digest" ]; then
|
||||
curl -s -X DELETE -H "Accept: application/vnd.docker.distribution.manifest.v2+json" "http://admin:Xiaoxia2026@localhost:5000/v2/${repo_name}/manifests/${digest}" > /dev/null 2>&1 || true
|
||||
echo " Deleted registry tag: ${svc}:${ver}"
|
||||
fi
|
||||
done
|
||||
|
||||
echo "[Local] Removing old local images for ${svc}..."
|
||||
for ver in $to_remove; do
|
||||
docker rmi "${svc}:${ver}" 2>/dev/null && echo " Removed local: ${svc}:${ver}" || true
|
||||
docker rmi "${REGISTRY_HOST}/${svc}:${ver}" 2>/dev/null && echo " Removed registry-ref: ${REGISTRY_HOST}/${svc}:${ver}" || true
|
||||
done
|
||||
else
|
||||
echo "[${svc}] ${total} version(s) found, within keep limit (${KEEP_VERSIONS})"
|
||||
fi
|
||||
echo ""
|
||||
done
|
||||
|
||||
# 清理悬空镜像(构建中间层)
|
||||
echo "=== Pruning dangling images ==="
|
||||
pruned=$(docker image prune -f 2>&1)
|
||||
echo "$pruned" | tail -1
|
||||
|
||||
# 清理 dev 标签的旧层(dev 标签会被下次构建覆盖)
|
||||
echo ""
|
||||
echo "=== Cleanup complete ==="
|
||||
echo "Current images:"
|
||||
docker images --format "table {{.Repository}}\t{{.Tag}}\t{{.Size}}" | grep -E "(xiaoxia|REPOSITORY)" || true
|
||||
Reference in New Issue
Block a user