From 340fa43fafe7b29df1ea9e5eb9ef43157e368f8c Mon Sep 17 00:00:00 2001 From: Saqib Date: Thu, 3 Sep 2026 11:49:40 +0530 Subject: [PATCH] ci: fail the build if the image exceeds a size ceiling Image size is a deploy-time failure mode here and nothing surfaced it. The image reached 14.1GB - 6.6GB of it CUDA runtime on a GPU-less box - and docker pull then ran past the deploy step's 40 minute command_timeout, so deploys failed with "Run Command Timeout" and no indication of the cause. Builds stayed green throughout; the cost only appeared on the host, an hour later, on an environment that could no longer be deployed to. Fails the build instead, so the feedback lands on the PR that caused it. The ceiling is 8GB against a current 3.56GB - set from the measured size after the CPU-only torch fix, with room for ordinary growth but not for another multi-gigabyte dependency arriving unnoticed. The error message names the usual culprits so whoever hits it knows where to look. --- .github/workflows/deploy-backend.yml | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/.github/workflows/deploy-backend.yml b/.github/workflows/deploy-backend.yml index 17907a0..bacde4f 100644 --- a/.github/workflows/deploy-backend.yml +++ b/.github/workflows/deploy-backend.yml @@ -116,6 +116,33 @@ jobs: run: | echo "image_ref=${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}@${{ steps.build.outputs.digest }}" >> "$GITHUB_OUTPUT" + # A size ceiling, because image size is a deploy-time failure mode here + # and nothing else surfaces it. The image reached 14.1GB - 6.6GB of it + # CUDA runtime on a GPU-less box - and `docker pull` then ran past the + # deploy step's 40 minute command_timeout, so deploys failed with + # "Run Command Timeout" and no indication of why. Builds stayed green + # throughout; the cost only appeared on the host. + # + # Fails the build rather than the deploy, so the feedback lands on the + # PR that caused it instead of an hour later on a broken environment. + # Raise MAX_IMAGE_GB deliberately if the image legitimately grows. + - name: Enforce image size ceiling + env: + MAX_IMAGE_GB: 8 + run: | + set -euo pipefail + docker pull -q "${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}@${{ steps.build.outputs.digest }}" + BYTES=$(docker image inspect \ + "${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}@${{ steps.build.outputs.digest }}" \ + --format "{{.Size}}") + GB=$(awk -v b="$BYTES" 'BEGIN{printf "%.2f", b/1024/1024/1024}') + echo "Image size: ${GB} GB (ceiling ${MAX_IMAGE_GB} GB)" + echo "- image size: **${GB} GB** (ceiling ${MAX_IMAGE_GB} GB)" >> "$GITHUB_STEP_SUMMARY" + if awk -v g="$GB" -v m="$MAX_IMAGE_GB" 'BEGIN{exit !(g > m)}'; then + echo "::error::Image is ${GB} GB, over the ${MAX_IMAGE_GB} GB ceiling. Pulling this on the deploy host will run past the SSH command_timeout and the deploy will fail. Check for CUDA/GPU wheels (nvidia/*, torch, triton) being pulled in place of CPU builds." + exit 1 + fi + - name: Sanity-check the built image # Cheap, real gate: catches import errors and bad settings before # anything touches the host. Live testing showed every layer