diff --git a/Jenkinsfile.pjt b/Jenkinsfile.pjt index eb8687c..8ad3f9b 100644 --- a/Jenkinsfile.pjt +++ b/Jenkinsfile.pjt @@ -213,22 +213,40 @@ pipeline { ${SSH_USER}@${SSH_HOST} \ 'set -e - echo "[0] Collect images used by running containers" - RUNNING_IMAGES=$(docker ps -q | xargs -r docker inspect --format="{{.Image}}" | sort -u) + REPO="${REGISTRY_HOST}/${IMAGE_REPO}" - echo "[1/3] Remove old registry images (except running ones)" - docker images '"${REGISTRY_HOST}/${IMAGE_REPO}"' --format "{{.ID}} {{.CreatedAt}}" | \ - sort -k2 -r | \ - awk "{print \$1}" | \ - while read IMAGE_ID; do - echo "$RUNNING_IMAGES" | grep -q "$IMAGE_ID" && continue - docker rmi -f "$IMAGE_ID" 2>/dev/null || true - done + echo "[0] Repo: $REPO" - echo "[2/3] Remove dangling images (safe)" + echo "[1] Collect running image refs (repo:tag) to protect" + RUNNING_REFS=$(docker ps --format "{{.Image}}" | grep -E "^${REPO}:" | sort -u || true) + + if [ -n "$RUNNING_REFS" ]; then + echo "Running refs (protected):" + echo "$RUNNING_REFS" | sed "s/^/ - /" + else + echo "No running refs found for $REPO (check if you run by digest or different name)" + fi + + echo "[2] Remove stopped containers (so they dont hold images)" + docker container prune -f + + echo "[3] List all local refs for repo" + ALL_REFS=$(docker images "$REPO" --format "{{.Repository}}:{{.Tag}}" | grep -v "" | sort -u || true) + + echo "[4] Remove repo images except protected running refs" + for REF in $ALL_REFS; do + if [ -n "$RUNNING_REFS" ] && echo "$RUNNING_REFS" | grep -qx "$REF"; then + echo "Skip running: $REF" + continue + fi + echo "Removing: $REF" + docker rmi -f "$REF" || true + done + + echo "[5] Remove dangling images" docker image prune -f - echo "[3/3] Remove unused volumes (safe)" + echo "[6] Remove unused volumes" docker volume prune -f ' ''' @@ -236,87 +254,5 @@ pipeline { } } - stage('12) Registry cleanup (keep last 5 + protect running)') { - steps { - withCredentials([usernamePassword( - credentialsId: DOCKER_CRED, - usernameVariable: 'DOCKER_USER', - passwordVariable: 'DOCKER_PASS' - )]) { - sshagent(['ssh-pjt']) { - sh '''#!/usr/bin/env bash - set -e - - ssh -p ${SSH_PORT} -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null \ - ${SSH_USER}@${SSH_HOST} \ - "REGISTRY_HOST='${REGISTRY_HOST}' IMAGE_REPO='${IMAGE_REPO}' DOCKER_USER='${DOCKER_USER}' DOCKER_PASS='${DOCKER_PASS}' bash -se" <<'REMOTE_EOF' - set -e - - REGISTRY_URL="https://${REGISTRY_HOST}" - REPO="${IMAGE_REPO}" - KEEP=5 - AUTH="${DOCKER_USER}:${DOCKER_PASS}" - - command -v jq >/dev/null 2>&1 || (sudo apt-get update -y && sudo apt-get install -y jq) - - echo "[1/6] Debug URL" - echo "TAGS_URL=${REGISTRY_URL}/v2/${REPO}/tags/list" - - echo "[2/6] Collect running tags to protect" - RUNNING_TAGS=$(docker ps --format '{{.Image}}' | \ - grep -E "^${REGISTRY_HOST}/${REPO}:" | \ - awk -F: '{print $2}' | sort -u || true) - - echo "[3/6] Fetch tags from registry" - TAGS=$(curl -fsS -u "${AUTH}" "${REGISTRY_URL}/v2/${REPO}/tags/list" | jq -r '.tags[]?' || true) - - if [ -z "$TAGS" ]; then - echo "No tags found in registry. Skip." - exit 0 - fi - - echo "[4/6] Sort tags desc" - SORTED=$(echo "$TAGS" | sort -r) - KEEP_TAGS=$(echo "$SORTED" | head -n $KEEP) - DEL_CANDIDATES=$(echo "$SORTED" | tail -n +$((KEEP+1))) - - echo "Keep tags:" - echo "$KEEP_TAGS" | sed 's/^/ - /' - - echo "[5/6] Delete old tags except running tags" - for TAG in $DEL_CANDIDATES; do - if [ -n "$RUNNING_TAGS" ] && echo "$RUNNING_TAGS" | grep -qx "$TAG"; then - echo "Skip running tag: ${REPO}:${TAG}" - continue - fi - - echo "Deleting ${REPO}:${TAG}" - - DIGEST=$(curl -fsSI -u "${AUTH}" \ - -H "Accept: application/vnd.docker.distribution.manifest.v2+json" \ - "${REGISTRY_URL}/v2/${REPO}/manifests/${TAG}" \ - | awk -F': ' '/Docker-Content-Digest/ {print $2}' | tr -d '\r') - - if [ -z "$DIGEST" ]; then - echo " digest not found. skip ${TAG}" - continue - fi - - curl -fsS -u "${AUTH}" -X DELETE "${REGISTRY_URL}/v2/${REPO}/manifests/${DIGEST}" || true - done - - echo "[6/6] Garbage collect (reclaim disk)" - docker exec registry registry garbage-collect /etc/docker/registry/config.yml - - echo "Registry cleanup done." - REMOTE_EOF - ''' - } - } - } - } - - - } }