Continuous delivery: build once, release many times
🎯You'll be able to
Explain continuous delivery and deployment, build one versioned artefact per change, and promote that same artefact through environments.
🏠The everyday picture
A publisher prints one edition of a book and sends copies of that same print run to every shop. They don't reprint it separately for each city, where a different printer might make a different mistake.
📘What it really is
-
Continuous delivery: every change that passes the pipeline is ready to release, and releasing is a routine, push-button step. Continuous deployment goes further: every passing change is released automatically, with no button.
-
Build once: the pipeline builds the image a single time, tags it with a unique version (
routerani:1.0.42or the commit SHA), and every environment runs that exact image. Rebuilding for production can pick up different dependencies, so what you tested isn't what you ship. -
Promote, don't rebuild: staging gets
1.0.42, checks pass, then production gets1.0.42. Settings that differ by environment come from outside the image (CD2 Lesson 5). -
Deploy and release are different:
- a deploy puts new code on servers;
-
a release makes a feature available to users. Feature flags let you deploy code switched off, then turn it on for 1% of users, then everyone, without another deploy.
-
Small and often: a release with one change is easy to check and easy to undo. A release with three months of changes is a risk, and when it breaks, nobody knows which change caused it.
-
Measures of delivery (the DORA metrics): how often you deploy, how long a change takes to reach production, how often a deploy causes a failure, and how long it takes to recover.
📝A worked example
Input: in the finished kit, run node tools/pipeline.js 1.0.1 and then node tools/pipeline.js 1.0.2.
Expected output: each run tests, builds routerani:<version>, deploys and verifies it, then writes the live version to
infra/release.auto.tfvars. docker images routerani lists both versions, so going back to 1.0.1 needs no rebuild. Running
node tools/pipeline.js latest stops straight away with a usage message, because a moving tag can't identify a release (Project 2 test 5).
🌍Where it's used
- Large tech companies deploy hundreds or thousands of times a day using continuous deployment and feature flags.
- Banks often use continuous delivery with a person approving production releases.
- App stores add review delays for mobile apps, so mobile teams rely heavily on feature flags.
📝Case scenario
An insurance company rebuilt its app separately for production after testing in staging. One Friday, a library had released a new version between the two builds; production got it, staging hadn't. Claims uploads broke for the weekend. Afterwards, the pipeline built once and promoted the same image digest, and the problem class disappeared.
🖱️Try it
Run the pipeline twice with different versions, then cat infra/release.auto.tfvars and docker images routerani. Success: you can say which
version is live, where that's recorded, and which image a rollback would use.
⚠️Common mistakes
- Rebuilding per environment. Sign: "it worked in staging". Fix: build once, promote the same image.
- Huge, rare releases. Sign: release days that everyone dreads. Fix: small changes, released often.
- Treating deploy as release. Sign: features appear for everyone the moment code ships. Fix: feature flags for risky changes.
🛠️For your project
Project 2 builds each version once with its own tag, refuses latest, and records the live version for rollbacks and the autoscaler.
✅Quick check
What's the difference between continuous delivery and continuous deployment?
Show the answer
Delivery keeps every passing change ready to release with a button; deployment releases it automatically.
Why build an image only once?
Show the answer
So the image you tested is exactly the one that reaches production.
