Production builds
🏠The everyday picture
A cake made for a competition is different from the one you test in your own kitchen: the same recipe, but measured precisely, decorated, boxed, and nothing half-finished left on it.
📘What it really is
- A production build is the version of your app made for real users:
- frontend:
npm run buildmakes minified, compressed files with hashed names (cacheable for a long time); development warnings and tools are removed; environment variables are built in (only public ones! Module 38); - backend: TypeScript compiled (or checked),
NODE_ENV=production, only production dependencies installed (npm ci --omit=dev), in a slim container image (Module 69). -
Build once, deploy many: build one image, give it a version tag (the Git commit, or a version number), and deploy the same image to staging and then production. Never rebuild for production; rebuilding can produce something slightly different from what you tested.
-
Push images to a registry (GitHub Container Registry, Docker Hub, or your cloud's registry), from which servers pull them.
-
Source maps help debug production errors (Module 39); upload them to your error-reporting service rather than serving them publicly if your code should stay private.
-
Check the production build locally before deploying:
npm run previewfor the frontend; run the API image with production settings.
🖱️Try it
Tag your API image with the current Git commit (docker build -t ghcr.io/YOUR-NAME/crm-api:$(git rev-parse --short HEAD) .),
log in to GitHub Container Registry with a personal access token that has only the package permissions, and push it. Check it
appears under your GitHub profile's Packages, and keep it private.
✅Quick check
What does "build once, deploy many" mean?
Show the answer
Build one versioned image and deploy that same image to every environment, so production runs exactly what was tested.
Why tag images with the Git commit?
Show the answer
You always know exactly which code is running, and can redeploy any earlier version.
