fix: optimize Docker image management during deployment

Enhance the deployment scripts for Finland and Iran by refining Docker image pruning and transfer processes. Implement conditional transfer compression using zstd or gzip based on availability, and ensure only unused admin tags are removed without affecting build cache. This improves efficiency and reduces unnecessary image deletions during deployments.
This commit is contained in:
alisaza 2026-09-13 18:47:38 +03:30
parent 8fe5f70ae5
commit bd8bc31ee0
2 changed files with 45 additions and 7 deletions

View File

@ -77,7 +77,8 @@ sanitize_api_proxy_target() {
esac esac
} }
# Avoid glob expansion when sourcing cron-like values already done; build args only. # DOCKER_BUILDKIT keeps layer/build cache across deploys; never prune -af here.
export DOCKER_BUILDKIT=1
docker build --platform linux/amd64 -t "$IMAGE_TAG" \ docker build --platform linux/amd64 -t "$IMAGE_TAG" \
--build-arg "NEXT_PUBLIC_API_URL=$(env_or_empty NEXT_PUBLIC_API_URL)" \ --build-arg "NEXT_PUBLIC_API_URL=$(env_or_empty NEXT_PUBLIC_API_URL)" \
--build-arg "NEXT_PUBLIC_FILE_SERVER_URL=$(env_or_empty NEXT_PUBLIC_FILE_SERVER_URL)" \ --build-arg "NEXT_PUBLIC_FILE_SERVER_URL=$(env_or_empty NEXT_PUBLIC_FILE_SERVER_URL)" \
@ -97,7 +98,8 @@ docker build --platform linux/amd64 -t "$IMAGE_TAG" \
--build-arg "API_PROXY_TARGET=$(sanitize_api_proxy_target)" \ --build-arg "API_PROXY_TARGET=$(sanitize_api_proxy_target)" \
"$SRC_DIR" "$SRC_DIR"
docker image prune -af >/dev/null 2>&1 || true # فقط dangling؛ prune -a/-af کش build را می‌کشد و هر deploy را cold می‌کند
docker image prune -f >/dev/null 2>&1 || true
echo "BUILT $IMAGE_TAG" echo "BUILT $IMAGE_TAG"
REMOTE REMOTE
@ -116,9 +118,21 @@ if [[ -f deploy/nginx/backoffice.conf ]]; then
' '
fi fi
echo "Transferring ${IMAGE_TAG} Finland → Iran..." # فشرده‌سازی transfer؛ zstd اگر روی هر دو host باشد، وگرنه gzip
"${FSSH[@]}" "${FINLAND_USER}@${FINLAND_HOST}" "docker save '${IMAGE_TAG}'" \ TRANSFER_CODEC=gzip
| "${ISSH[@]}" "${IRAN_USER}@${IRAN_HOST}" "docker load" if "${FSSH[@]}" "${FINLAND_USER}@${FINLAND_HOST}" 'command -v zstd >/dev/null 2>&1' \
&& "${ISSH[@]}" "${IRAN_USER}@${IRAN_HOST}" 'command -v zstd >/dev/null 2>&1'; then
TRANSFER_CODEC=zstd
fi
echo "Transferring ${IMAGE_TAG} Finland → Iran (${TRANSFER_CODEC})..."
if [[ "$TRANSFER_CODEC" == zstd ]]; then
"${FSSH[@]}" "${FINLAND_USER}@${FINLAND_HOST}" "docker save '${IMAGE_TAG}' | zstd -T0 -3" \
| "${ISSH[@]}" "${IRAN_USER}@${IRAN_HOST}" 'zstd -d | docker load'
else
"${FSSH[@]}" "${FINLAND_USER}@${FINLAND_HOST}" "docker save '${IMAGE_TAG}' | gzip -1" \
| "${ISSH[@]}" "${IRAN_USER}@${IRAN_HOST}" 'gzip -d | docker load'
fi
"${ISSH[@]}" "${IRAN_USER}@${IRAN_HOST}" \ "${ISSH[@]}" "${IRAN_USER}@${IRAN_HOST}" \
"ADMIN_IMAGE='${IMAGE_TAG}' bash -s" <<'REMOTE' "ADMIN_IMAGE='${IMAGE_TAG}' bash -s" <<'REMOTE'
@ -130,7 +144,13 @@ for attempt in $(seq 1 36); do
health="$(docker inspect --format '{{if .State.Health}}{{.State.Health.Status}}{{else}}{{.State.Status}}{{end}}' ghabilee-admin 2>/dev/null || echo missing)" health="$(docker inspect --format '{{if .State.Health}}{{.State.Health.Status}}{{else}}{{.State.Status}}{{end}}' ghabilee-admin 2>/dev/null || echo missing)"
echo "Admin health ${attempt}/36: ${health}" echo "Admin health ${attempt}/36: ${health}"
if [ "$health" = healthy ]; then if [ "$health" = healthy ]; then
docker image prune -af >/dev/null 2>&1 || true # آزاد کردن دیسک بدون نابود کردن کش: فقط tagهای قدیمی admin که در حال استفاده نیستند
docker images --format '{{.Repository}}:{{.Tag}}' \
| awk -v keep="$ADMIN_IMAGE" '$0 ~ /^ghabilee-admin:/ && $0 != keep { print }' \
| while IFS= read -r old; do
docker rmi "$old" >/dev/null 2>&1 || true
done
docker image prune -f >/dev/null 2>&1 || true
echo "Deploy OK" echo "Deploy OK"
exit 0 exit 0
fi fi
@ -139,3 +159,15 @@ for attempt in $(seq 1 36); do
done done
exit 1 exit 1
REMOTE REMOTE
# روی Finland هم tagهای قدیمی admin را بردار؛ BuildKit cache دست‌نخورده می‌ماند
"${FSSH[@]}" "${FINLAND_USER}@${FINLAND_HOST}" \
"IMAGE_TAG='${IMAGE_TAG}' bash -s" <<'REMOTE'
set -euo pipefail
docker images --format '{{.Repository}}:{{.Tag}}' \
| awk -v keep="$IMAGE_TAG" '$0 ~ /^ghabilee-admin:/ && $0 != keep { print }' \
| while IFS= read -r old; do
docker rmi "$old" >/dev/null 2>&1 || true
done
docker image prune -f >/dev/null 2>&1 || true
REMOTE

View File

@ -84,7 +84,13 @@ for attempt in $(seq 1 36); do
health="$(docker inspect --format '{{if .State.Health}}{{.State.Health.Status}}{{else}}{{.State.Status}}{{end}}' ghabilee-admin 2>/dev/null || echo missing)" health="$(docker inspect --format '{{if .State.Health}}{{.State.Health.Status}}{{else}}{{.State.Status}}{{end}}' ghabilee-admin 2>/dev/null || echo missing)"
echo "Admin health ${attempt}/36: ${health}" echo "Admin health ${attempt}/36: ${health}"
if [ "$health" = "healthy" ]; then if [ "$health" = "healthy" ]; then
docker image prune -af >/dev/null 2>&1 || true # فقط tagهای قدیمی admin؛ prune -af کش/لایه‌های قابل‌استفاده مجدد را پاک می‌کند
docker images --format '{{.Repository}}:{{.Tag}}' \
| awk -v keep="$IMAGE_TAG" '$0 ~ /^ghabilee-admin:/ && $0 != keep { print }' \
| while IFS= read -r old; do
docker rmi "$old" >/dev/null 2>&1 || true
done
docker image prune -f >/dev/null 2>&1 || true
echo "Deploy OK" echo "Deploy OK"
exit 0 exit 0
fi fi