From 0113509fa17c49f93550c655d941aea859b2ad69 Mon Sep 17 00:00:00 2001 From: Talha Ahmed Date: Thu, 3 Sep 2026 18:39:43 +0500 Subject: [PATCH] Deploy: stop shipping 90 MB of node_modules the build throws away MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The S3 artifact is 32.9 MiB compressed. Every other project's zip in that bucket is under 1 MiB. The difference is frontend/node_modules, which is committed to this repo and so was swept into every upload. Earlier I left it in because nothing in the repo says what consumes the bucket object, and if that side ran the app without installing dependencies, dropping it would have broken the deploy. That is now answered rather than assumed. Traced on the instance: CodeDeploy extracts to /opt/codedeploy-extracted-5, the AfterInstall hook copies the tree to /home/ec2-user/utopia-ai-hr-ats-portal-deployment-group, then runs `docker compose --env-file ./backend/.env up -d --build`. Eleven containers come up and the only Node one is hrms-frontend, built from frontend/Dockerfile, which does `npm ci` against the lockfile. On top of that frontend/.dockerignore excludes node_modules/ from the build context outright, so even the copy that arrived could not have been read. It was carried across the wire on every merge to main and then discarded unread. The exclusion patterns were verified rather than trusted: zip -r with -x on a synthetic tree in a temp dir on the box, since zip is not available locally. That run also confirmed the previous commit's other fix — the original `-x ".gitignore/*"` really did fail to match the file, and `-x ".gitignore"` matches it. Not done here, deliberately: node_modules is still tracked in git, which is why it was in the artifact in the first place. Untracking it deletes 5,230 files from every other contributor's working tree on their next pull, across thirteen active branches, and needs a heads-up rather than a surprise. Two things found while reading the deploy script, neither touched: - It copies with `cp -r` and never deletes, so a file removed from the repo survives on the server indefinitely. Switching to a delete-on-sync would risk backend/.env, which the script deliberately preserves. - It re-downloads the latest docker compose and buildx from GitHub on every single deploy, unpinned, as root. Co-Authored-By: Claude Opus 5 (1M context) --- .gitea/workflows/deploy-to-s3.yml | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-) diff --git a/.gitea/workflows/deploy-to-s3.yml b/.gitea/workflows/deploy-to-s3.yml index b4102e0..c5883f0 100644 --- a/.gitea/workflows/deploy-to-s3.yml +++ b/.gitea/workflows/deploy-to-s3.yml @@ -47,12 +47,18 @@ jobs: - name: Checkout repository uses: actions/checkout@v3 - # NOTE: this zip still contains frontend/node_modules, roughly 90 MB and - # the bulk of the artifact. It is left in deliberately. Nothing in this - # repo says what unpacks the zip on the other side — there is no appspec - # file and no deploy script here — so if that side runs the app without - # installing dependencies, dropping node_modules would break the deploy. - # Confirm what consumes the bucket object, then add -x "frontend/node_modules/*". + # frontend/node_modules is excluded, and that is safe because of what + # happens to this object downstream. CodeDeploy pulls it, extracts to + # /opt/codedeploy-extracted-5, copies the tree to + # /home/ec2-user/utopia-ai-hr-ats-portal-deployment-group and runs + # `docker compose --env-file ./backend/.env up -d --build`. The only Node + # service is the frontend, whose image does `npm ci` from the lockfile, + # and frontend/.dockerignore excludes node_modules/ from the build context + # outright. So the committed tree was carried into every artifact and then + # thrown away unread. It was 90 MB of a 33 MB compressed upload. + # + # node_modules is still tracked in git, which is the reason it was here at + # all. Untracking it is a separate change and affects other branches. - name: Archive project run: | apt-get update -y @@ -61,6 +67,7 @@ jobs: -x ".git/*" \ -x ".gitea/*" \ -x ".gitignore" \ + -x "frontend/node_modules/*" \ -x "*.DS_Store" - name: Install AWS CLI