[api] Jenkinsfile.pjt
- 삭제정책 추가
This commit is contained in:
+51
-85
@@ -100,17 +100,14 @@ pipeline {
|
|||||||
sh '''
|
sh '''
|
||||||
set -e
|
set -e
|
||||||
|
|
||||||
echo "[1/4] Remove pushed image from Jenkins"
|
echo "[1/3] Remove pushed image from Jenkins"
|
||||||
docker rmi ${REGISTRY_HOST}/${IMAGE_REPO}:${IMAGE_TAG} 2>/dev/null || true
|
docker rmi ${REGISTRY_HOST}/${IMAGE_REPO}:${IMAGE_TAG} 2>/dev/null || true
|
||||||
|
|
||||||
echo "[2/4] Remove dangling images"
|
echo "[2/3] Remove dangling images"
|
||||||
docker image prune -f
|
docker image prune -f
|
||||||
|
|
||||||
echo "[3/4] Remove old build cache (safe-ish)"
|
echo "[3/3] Remove old build cache (safe-ish)"
|
||||||
# 빌드 캐시만 정리: 다른 컨테이너/볼륨에는 영향 적음
|
|
||||||
docker builder prune -f || true
|
docker builder prune -f || true
|
||||||
|
|
||||||
echo "[4/4] Skip docker system prune --volumes (too aggressive on shared nodes)"
|
|
||||||
'''
|
'''
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -241,100 +238,69 @@ pipeline {
|
|||||||
|
|
||||||
stage('12) Registry cleanup (keep last 5 + protect running)') {
|
stage('12) Registry cleanup (keep last 5 + protect running)') {
|
||||||
steps {
|
steps {
|
||||||
sshagent(['ssh-pjt']) {
|
withCredentials([usernamePassword(
|
||||||
sh '''
|
credentialsId: DOCKER_CRED,
|
||||||
set -e
|
usernameVariable: 'DOCKER_USER',
|
||||||
ssh -p ${SSH_PORT} -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null \
|
passwordVariable: 'DOCKER_PASS'
|
||||||
${SSH_USER}@${SSH_HOST} \
|
)]) {
|
||||||
'set -e
|
sshagent(['ssh-pjt']) {
|
||||||
|
sh '''
|
||||||
|
set -e
|
||||||
|
ssh -p ${SSH_PORT} -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null \
|
||||||
|
${SSH_USER}@${SSH_HOST} \
|
||||||
|
'set -e
|
||||||
|
REGISTRY_URL="https://${REGISTRY_HOST}"
|
||||||
|
REPO="${IMAGE_REPO}"
|
||||||
|
KEEP=5
|
||||||
|
AUTH="'${DOCKER_USER}':'${DOCKER_PASS}'"
|
||||||
|
|
||||||
REGISTRY_URL="https://'${REGISTRY_HOST}'" # 예: https://registry.pjt.kr
|
command -v jq >/dev/null 2>&1 || (sudo apt-get update -y && sudo apt-get install -y jq)
|
||||||
REPO="'${IMAGE_REPO}'" # 예: alist/api
|
|
||||||
KEEP=5
|
|
||||||
|
|
||||||
# (옵션) Basic Auth 쓰면 아래 활성화하고 curl에 -u "$AUTH" 추가
|
echo "[1/5] Collect running tags to protect"
|
||||||
# AUTH="user:pass"
|
RUNNING_TAGS=$(docker ps --format "{{.Image}}" | \
|
||||||
|
grep -E "^${REGISTRY_HOST}/${IMAGE_REPO}:" | \
|
||||||
|
awk -F: "{print \\$2}" | sort -u || true)
|
||||||
|
|
||||||
echo "[0/5] Ensure jq exists"
|
echo "[2/5] Fetch tags from registry"
|
||||||
if ! command -v jq >/dev/null 2>&1; then
|
TAGS=$(curl -fsS -u "$AUTH" "$REGISTRY_URL/v2/$REPO/tags/list" | jq -r ".tags[]?" || true)
|
||||||
sudo apt-get update -y
|
|
||||||
sudo apt-get install -y jq
|
|
||||||
fi
|
|
||||||
|
|
||||||
echo "[1/5] Collect running tags to protect"
|
[ -z "$TAGS" ] && { echo "No tags found. Skip."; exit 0; }
|
||||||
# 현재 서버에서 실행 중인 컨테이너가 사용하는 해당 레포 이미지 태그만 추출
|
|
||||||
RUNNING_TAGS=$(docker ps --format "{{.Image}}" | \
|
|
||||||
grep -E "^'${REGISTRY_HOST}'/'${IMAGE_REPO}':" | \
|
|
||||||
awk -F: "{print \\$2}" | sort -u || true)
|
|
||||||
|
|
||||||
if [ -n "$RUNNING_TAGS" ]; then
|
echo "[3/5] Sort tags desc"
|
||||||
echo "Running tags (protected):"
|
SORTED=$(echo "$TAGS" | sort -r)
|
||||||
echo "$RUNNING_TAGS" | sed "s/^/ - /"
|
KEEP_TAGS=$(echo "$SORTED" | head -n $KEEP)
|
||||||
else
|
DEL_CANDIDATES=$(echo "$SORTED" | tail -n +$((KEEP+1)))
|
||||||
echo "No running tags found for ${REGISTRY_HOST}/${IMAGE_REPO} (ok)"
|
|
||||||
fi
|
|
||||||
|
|
||||||
echo "[2/5] Fetch tags from registry: $REPO"
|
echo "Keep tags:"
|
||||||
TAGS=$(curl -fsS "$REGISTRY_URL/v2/$REPO/tags/list" | jq -r ".tags[]?" || true)
|
echo "$KEEP_TAGS" | sed "s/^/ - /"
|
||||||
# Basic Auth 쓰면 위 curl을 아래로 바꿔:
|
|
||||||
# TAGS=$(curl -fsS -u "$AUTH" "$REGISTRY_URL/v2/$REPO/tags/list" | jq -r ".tags[]?" || true)
|
|
||||||
|
|
||||||
if [ -z "$TAGS" ]; then
|
echo "[4/5] Delete old tags except running tags"
|
||||||
echo "No tags found in registry. Skip."
|
for TAG in $DEL_CANDIDATES; do
|
||||||
exit 0
|
if [ -n "$RUNNING_TAGS" ] && echo "$RUNNING_TAGS" | grep -qx "$TAG"; then
|
||||||
fi
|
echo "Skip running tag: $REPO:$TAG"
|
||||||
|
continue
|
||||||
|
fi
|
||||||
|
|
||||||
echo "[3/5] Sort tags desc (tag must be sortable for 'latest' semantics)"
|
DIGEST=$(curl -fsSI -u "$AUTH" \
|
||||||
SORTED=$(echo "$TAGS" | sort -r)
|
-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")
|
||||||
|
|
||||||
KEEP_TAGS=$(echo "$SORTED" | head -n $KEEP)
|
[ -z "$DIGEST" ] && { echo "digest not found. skip $TAG"; continue; }
|
||||||
DEL_CANDIDATES=$(echo "$SORTED" | tail -n +$((KEEP+1)))
|
|
||||||
|
|
||||||
echo "Keep tags (latest $KEEP):"
|
curl -fsS -u "$AUTH" -X DELETE "$REGISTRY_URL/v2/$REPO/manifests/$DIGEST" || true
|
||||||
echo "$KEEP_TAGS" | sed "s/^/ - /"
|
done
|
||||||
|
|
||||||
echo "[4/5] Delete old tags except protected running tags"
|
echo "[5/5] Garbage collect"
|
||||||
for TAG in $DEL_CANDIDATES; do
|
docker exec registry registry garbage-collect /etc/docker/registry/config.yml
|
||||||
# 실행 중 태그는 무조건 스킵
|
|
||||||
if [ -n "$RUNNING_TAGS" ] && echo "$RUNNING_TAGS" | grep -qx "$TAG"; then
|
|
||||||
echo "Skip running tag: $REPO:$TAG"
|
|
||||||
continue
|
|
||||||
fi
|
|
||||||
|
|
||||||
echo "Deleting $REPO:$TAG"
|
echo "Registry cleanup done."
|
||||||
|
'
|
||||||
DIGEST=$(curl -fsSI \
|
'''
|
||||||
-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")
|
|
||||||
|
|
||||||
# Basic Auth 쓰면 위 curl을 아래로 바꿔:
|
|
||||||
# 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 -X DELETE "$REGISTRY_URL/v2/$REPO/manifests/$DIGEST" || true
|
|
||||||
# Basic Auth 쓰면:
|
|
||||||
# curl -fsS -u "$AUTH" -X DELETE "$REGISTRY_URL/v2/$REPO/manifests/$DIGEST" || true
|
|
||||||
done
|
|
||||||
|
|
||||||
echo "[5/5] Garbage collect (reclaim disk space)"
|
|
||||||
# push가 진행 중이면 위험할 수 있으니, 배포 성공 후 마지막 단계에서만 실행 추천
|
|
||||||
docker exec registry registry garbage-collect /etc/docker/registry/config.yml
|
|
||||||
|
|
||||||
echo "Registry cleanup done."
|
|
||||||
'
|
|
||||||
'''
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user