A deploy pipeline is the automated path your code takes from a commit to running in production. Done well, it's invisible: you push, and minutes later your change is live. Done poorly, it's a source of mystery failures and 2 a.m. rollbacks. This guide breaks the pipeline into its stages, explains what each does, and flags the common failure modes.
Why pipelines exist
Before automation, "deploying" meant a human SSHing into a server, pulling code, restarting processes, and praying. That's slow, error-prone, and unrepeatable — every deploy is a hand-crafted artisanal event. A pipeline replaces that with a deterministic, automated sequence so deploys become boring, frequent, and reversible. Boring is the goal.
The stages
Most pipelines, whatever the tool, follow this shape:
Source → Build → Test → Package → Deploy → Release → ObserveLet's walk each one.
1. Source
The trigger. A push (or merge, or tag) to your Git repository kicks off the pipeline. The pipeline checks out the exact commit so everything downstream operates on a known, immutable snapshot.
- Goes wrong when: ambiguous triggers (which branch deploys where?), or building from a moving reference instead of a pinned commit.
2. Build
Turn source into a runnable artifact — compile code, install dependencies, bundle assets, produce a container image. This stage should be reproducible: same input commit → same output artifact.
- Goes wrong when: builds depend on the machine's local state, missing lockfiles cause non-deterministic dependency versions, or builds run out of memory (the dreaded
exit code 137).
3. Test
Run automated checks against the build — unit tests, integration tests, linting, type checks, security scans. The pipeline's job is to stop bad code before it ships.
- Goes wrong when: flaky tests erode trust until people ignore failures, or there are no tests at all and the build stage is the only gate.
4. Package
Produce the immutable, deployable artifact and store it. For containers, this means building an image and pushing it to a registry (like Google Artifact Registry), addressed by tag or digest.
- Goes wrong when: artifacts aren't immutable (overwriting
:latest), making rollbacks ambiguous.
5. Deploy
Place the new version into the target environment. In Kubernetes this often means a rolling update via Helm: new pods come up, pass health checks, and old pods drain — ideally with zero downtime.
- Goes wrong when: no health checks, so broken pods take traffic; or no surge capacity, so a rollout briefly drops below needed replicas.
6. Release
Deploy and release are subtly different. *Deploy* puts the code in the environment; *release* directs user traffic to it. Decoupling them enables canary releases, blue/green, and feature flags — ship the code dark, then flip traffic gradually.
- Goes wrong when: deploy and release are fused, so every deploy is an all-at-once gamble.
7. Observe
After release, watch metrics, logs, and error rates. A pipeline isn't done at deploy — it's done when you've confirmed the new version is healthy. Many mature pipelines auto-rollback on a spike in errors.
- Goes wrong when: nobody watches, and a regression sits in production until users complain.
Stage responsibilities at a glance
| Stage | Input | Output | Primary risk |
|---|---|---|---|
| Source | Git event | Pinned commit | Wrong trigger |
| Build | Commit | Artifact/image | Non-reproducible build |
| Test | Artifact | Pass/fail gate | Flaky or absent tests |
| Package | Artifact | Immutable image in registry | Mutable tags |
| Deploy | Image | Running pods | No health checks |
| Release | Running pods | Traffic shifted | All-at-once cutover |
| Observe | Live traffic | Confidence / rollback | No monitoring |
CI vs CD
Two overlapping terms:
- Continuous Integration (CI): source → build → test, run on every change to keep the main branch always-shippable.
- Continuous Delivery/Deployment (CD): extends through package → deploy → release. *Delivery* means it's automatically ready to deploy; *deployment* means it actually does, automatically.
Rollbacks: the safety net
A pipeline isn't trustworthy without a fast rollback. Because each release corresponds to an immutable artifact, rolling back is just redeploying the previous known-good image. This is why immutable packaging (stage 4) matters so much — it's what makes "undo" a one-click operation rather than a frantic re-build.
How this maps to PandaStack
PandaStack runs this whole pipeline for you from a Git push:
- 1Source: push to a connected repo.
- 2Build: rootless BuildKit in an ephemeral Kubernetes Job pod, with live, searchable logs.
- 3Package: image pushed to Google Artifact Registry.
- 4Deploy: Helm rollout onto multi-region GKE, behind Kong ingress with automatic SSL.
- 5Release/Observe: traffic routed, server-side metrics and analytics captured (ClickHouse), deploy history retained, and rollbacks available to a previous version.
You get the full stage sequence — including immutable artifacts and one-click rollback — without assembling the CI/CD plumbing yourself.
References
- [Martin Fowler: Continuous Integration](https://martinfowler.com/articles/continuousIntegration.html)
- [Continuous Delivery (Humble & Farley)](https://continuousdelivery.com/)
- [Kubernetes rolling updates](https://kubernetes.io/docs/tutorials/kubernetes-basics/update/update-intro/)
- [Helm documentation](https://helm.sh/docs/)
- [Feature flags / decoupling deploy and release](https://martinfowler.com/articles/feature-toggles.html)
---
PandaStack gives you a complete deploy pipeline — build, package, deploy, rollback — triggered by git push, with deploy history on the free tier (10 days, more on paid plans). Try it at [dashboard.pandastack.io](https://dashboard.pandastack.io).