How it works
The explanation, with examples you can run.
What each environment is for
Have as few environments as you can justify, and know the question each one answers:
- Local and CI: does the code build and pass its tests?
- Preview (one per pull request): does the change look and behave right to a reviewer? Short-lived and disposable.
- Staging: does it work with real-like infrastructure, data volumes and neighbouring services? Often where migrations and end-to-end tests run first.
- Production: does it work for users? Some things can only be learned here, which is why canaries and feature flags exist.
Environments that don't answer a distinct question ("QA2", "UAT-old") mostly add waiting.
Config comes from the environment
The same image runs everywhere, so anything that differs (URLs, credentials, feature defaults, resource sizes) is supplied at deploy time from environment variables, a config service or a secret store. That way:
- what you tested in staging is byte-for-byte what reaches production;
- secrets never sit inside an image someone can pull;
- a rollback is "deploy the previous digest", not "rebuild the old commit".
Promotion as a pipeline
# Sketch: one build, then deploy jobs that reuse its output.jobs: build: runs-on: ubuntu-latest steps: - run: echo "build and push the image, record its digest" deploy-staging: needs: build runs-on: ubuntu-latest environment: staging steps: - run: echo "deploy the digest from build to staging, then smoke test" deploy-production: needs: deploy-staging runs-on: ubuntu-latest environment: production # can require reviewers, a wait timer, or main only steps: - run: echo "deploy the same digest to production"In GitHub Actions, an environment can require reviewers, restrict which branches may deploy to it, and hold its own secrets. Other systems (Argo CD, Spinnaker, cloud deploy services) model the same idea as stages and approvals.
Keeping staging honest
Define every environment from the same infrastructure code (Terraform, Pulumi, Helm values) with parameters for size and names. Keep versions of databases, runtimes and managed services aligned. Seed staging with realistic data shapes, generated or anonymised, never raw copies of production personal data. And watch for the slow drift of manual fixes: if someone changes staging by hand, the next deploy from code should put it back.
Check yourself
3 questions. Get them all right to finish this topic.
0 of 3 right so far. Get all three to finish this topic.