Full Stack
Advanced 14 min read Full Stack

Deployment & Environments

Deployment is how your code becomes a running, reachable service with secrets and config injected per environment. Environments (dev, staging, prod), CI/CD pipelines, blue-green and canary strategies, feature flags and automated rollbacks turn shipping from a gamble into a repeatable process.

CI/CDstagingproductionenvironment variablessecretsblue-greencanaryrolling deployfeature flagsrollbackhealth checks
Introduction

What is this?

Deployment and environments are the layer between committed code and users. A CI/CD pipeline lints, type-checks, tests and builds an artifact, then promotes that same artifact through environments — development, staging and production — each with its own injected configuration and secrets. Deployment strategies decide how traffic moves to the new version: blue-green flips an entire environment, canary shifts a percentage gradually, rolling updates instances one at a time. Health checks, feature flags and rollbacks make a bad release survivable instead of fatal.

Motivation

Why do you need it?

  • Building once and promoting the same artifact means what passed staging is exactly what ships — no 'works on my machine'.
  • Staging with production parity catches config, migration and integration failures before users see them.
  • Blue-green and canary strategies let you ship with confidence and roll back in seconds instead of redeploying.
  • Environment variables and secret stores keep credentials out of the repository while injecting them per environment.
  • Automated health checks and rollbacks turn a failed release into a non-event for users.
Think about it

Mental model

Imagine

Dress rehearsal before opening night

Think of

Staging before production

You rehearse on the same stage, with the same lights, microphones and props you'll use in front of an audience. Running on a cardboard set at home (local dev) proves nothing about how the show performs on opening night.

Mechanics

How it works

  • A push to the trunk (or a PR merge) triggers CI: lint, typecheck, tests, then a build that produces a versioned artifact or container image.
  • The pipeline promotes the artifact to environments in order — development auto-deploys, staging deploys on approval, production deploys behind a manual gate.
  • Each environment injects its own env vars and secrets from the platform (Vercel, GitHub Actions secrets, Kubernetes Secrets), never from the repo.
  • The deploy strategy moves traffic: blue-green flips a load-balancer target, canary shifts N% then ramps based on error rates, rolling swaps instances in place.
  • Post-deploy health checks and smoke tests verify readiness; if they fail, the pipeline rolls back to the previous known-good version.

From commit to production with a progressive rollout.

Developer pushes
CI checks
Push artifact
Deploy to staging
Promote to production
Rollback on failure
Reference

Key commands

git push origin main

Trigger the CI/CD pipeline for the default branch.

npm run build

Produce the deployable artifact locally (dist/ or the container image).

gh run watch

Follow the latest GitHub Actions workflow run from the terminal.

✓ success in 2m 14s
vercel --env staging --token $VERCEL_TOKEN

Deploy the current build to the staging environment.

openssl rand -base64 32

Generate a random value to store as a secret.

gh secret set DB_URL

Store a secret in GitHub Actions without putting it in the repo.

Hands-on

Examples

A GitHub Actions pipeline that checks then deploys to staging

A GitHub Actions pipeline that checks then deploys to staging
name: CI + Deploy to staging
on:
push:
branches: [main]
jobs:
ci:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: 20
- run: npm ci
- run: npm run typecheck
- run: npm test
- run: npm run build
deploy-staging:
needs: ci
runs-on: ubuntu-latest
environment: staging
steps:
- uses: actions/checkout@v4
- run: npm ci
- run: npx vercel deploy --env staging --token ${{ secrets.VERCEL_TOKEN }}

The ci job gates everything: typecheck and tests must pass and the build must succeed before anything deploys. The deploy-staging job depends on ci and runs in the 'staging' GitHub environment, so its secrets (VERCEL_TOKEN) are scoped and the environment can carry its own approval rules.

Real world

In production

  • Every PR to a Vercel/Netlify project gets an isolated preview environment from the build — code review against a live deployment.
  • Kubernetes blue-green deploys give a full second environment; rollback is just flipping the service selector back.
  • Canary releases route 5% of traffic to the new version, watch error rates, then ramp to 25%, 50%, 100%.
  • Feature flags ship unfinished features to production 'dark', enabling per-tenant rollout without a redeploy.
Guidelines

Best practices

  • Build once and promote: the artifact that passed staging is the artifact that ships to production.
  • Keep secrets in the platform's secret store and inject them via env vars; never commit .env files.
  • Add a /healthz endpoint and wire it into the platform's health checks so bad deploys are caught before traffic arrives.
  • Automate rollbacks and practice them in staging so recovery is boring and fast.
  • Gate production deploys behind a manual approval step with a written rollback plan.
Watch out

Common mistakes

  • Committing .env files with real production secrets — one push leaks them to everyone who can clone.
  • Deploying from a developer's laptop instead of the CI artifact, so prod gets code CI never tested.
  • Blue-green flips without health checks, cutting traffic to a version that crashes immediately.
  • Assuming staging equals production when env vars, DB scale and integrations differ.
Root cause analysis

Common issues

Error
fatal: authentication failed (push to remote)
Root cause

The deploy credential or PAT used by CI expired or was revoked.

Fix

Rotate the credential, store the new value with gh secret set, and re-run the failed workflow.

Error
Container failed readiness probe / 503 on /healthz
Root cause

The app isn't ready when traffic is routed to it, or the health endpoint checks the wrong dependency.

Fix

Add a startup grace period and make /healthz report real readiness (DB connection, migrations applied) before returning 200.

Error
Deploy succeeded but users still see the old version
Root cause

A CDN or router cache, or the wrong tag was promoted.

Fix

Purge the cache, confirm the image SHA matches the registry, and force a fresh release if needed.

When things break

Debugging tips

  • Diff the injected environment variables between environments first — most 'works in staging' bugs are a missing prod env var.
  • Read deploy logs in order: image pulled → container started → readiness probe passing — the failing stage tells you the layer.
  • Use gh run view --log-failed to jump straight to the exact CI step that failed.
  • Confirm the deployed SHA matches the registry artifact tag; a mismatch means the CDN or router is serving the old build.
Interviews

Interview checkpoint

Practice

Hands-on lab

Deploy Across Environments and Roll Back
45 min · advanced
In progress
Objectives
  • Inject different configuration per environment from env vars
  • Build once and deploy the same artifact to staging and production
  • Add a health endpoint that reports the active environment
  • Practice a rollback to the previous version

Deploy Across Environments and Roll Back

45 min · advanced

0/5 steps
0%
sandbox · Linux sandbox
$
Try these commands
Test yourself

Quick quiz

0/3
1

Which environment should mirror production configuration so issues surface before users see them?

2

Committing your production .env file is a safe way to share secrets with the team.

3

You rolled a new version to 10% of traffic and the error rate spiked. What do you do next?

Quick reference

Cheat sheet

Deploy strategies
blue-greenTwo full envs, atomic traffic flip
canaryProgressive % traffic shift
rollingInstance-by-instance update
health checkGate traffic on readiness
feature flagToggle code without a redeploy
rollbackRevert to the previous version
Go deeper

Official documentation