Skip to main content

Environment Strategy: Dev, Test, Stage, Prod

Design environments that catch problems early without slowing development.

TL;DR

Development: Local laptop or shared dev server. Deploy on every commit. Fast feedback (<5 minutes). Unit + integration tests. Failures expected; fail fast and fix.

Test: Shared environment. Full integration tests. Can be shared with QA. Slower tests acceptable (1-30 minutes).

Staging: Production-like infrastructure. Replica of prod without real customer data. Full test suite runs here. Final validation before prod.

Production: Real users. Highest safety bar. Deployments approved by humans. This progression catches problems early (dev), validates thoroughly (staging), then rolls to production with confidence.

Learning Objectives

  • Design environment progression matching your risk profile
  • Implement fast feedback loops for developers
  • Manage data safely across environments
  • Control secrets per environment
  • Deploy consistently across environments
  • Balance speed and safety

Motivating Scenario

Your company has one shared environment. All developers deploy there. Tests take 30 minutes. When Alice breaks something, Bob's work is blocked. QA can't test because the environment is unstable. Deployments to prod are risky because staging doesn't match production. You lose a day per week to environment conflicts.

You need environments that let developers work fast without blocking each other.

Core Concepts

Environment Progression Flow

Development Environment

Purpose: Rapid feedback. Developer can test changes in seconds.

Characteristics: Local laptop or shared dev server. Auto-deploy on every commit. Fast tests (unit + quick integration) <10 min. May be unstable (developers iterating). Data is dummy/synthetic.

Failures: Expected. Developer sees error, fixes, redeploys immediately.

Test Environment

Purpose: Integration testing. Find problems unit tests miss.

Characteristics: Shared among developers. Full integration tests. 30 minutes for full suite. Closer to prod (but not identical). Data from templates or anonymized prod copies.

QA: Can manually test here. Feedback: "I found a bug" or "Feature works."

Staging Environment

Purpose: Final validation. Will this work in production?

Characteristics: Production-like infrastructure (same instance types, database, load balancer setup). Real customer data? No—use scrubbed/anonymized copy. Full test suite + performance tests. Closely matches prod except no real traffic.

Production Environment

Purpose: Serve real users. Highest safety bar.

Characteristics: Real customer data. Real traffic. Deployments require human approval. Monitoring and alerting critical. Rollback capability essential.

Practical Examples

# docker-compose.yml
version: '3.8'

services:
app:
build: .
ports:
- "8080:8080"
environment:
DATABASE_URL: postgresql://user:pass@postgres:5432/myapp_dev
REDIS_URL: redis://redis:6379
LOG_LEVEL: debug
depends_on:
- postgres
- redis
volumes:
- .:/app

postgres:
image: postgres:15
environment:
POSTGRES_USER: user
POSTGRES_PASSWORD: pass
POSTGRES_DB: myapp_dev
ports:
- "5432:5432"

redis:
image: redis:7
ports:
- "6379:6379"

Developer workflow: docker-compose up, tests run on every save, < 1 minute feedback.

When to Use / When Not to Use

Use 4-Environment Strategy When:
  1. Multiple teams working on the same product
  2. Complex deployments (database migrations, infrastructure changes)
  3. Compliance requires staging to mirror production
  4. Mature product with many users and uptime requirements
  5. Manual QA testing needed
Simplify to 2 Environments When:
  1. Small team working closely together
  2. Continuous deployment is safe (feature flags, canary deployments)
  3. Automated tests provide confidence
  4. Infrastructure is simple (serverless, single region)

Patterns and Pitfalls

Patterns and Pitfalls

Anti-pattern: One dev environment; all developers deploy there. Conflicts block work. Better: Local development for fast feedback. Shared test environment only for integration.
Anti-pattern: Staging uses smaller instances, different database version, missing load balancer. Issues found in staging don't show in prod. Better: Infrastructure as code ensures staging mirrors prod (except maybe scale for cost).
Anti-pattern: Copy production database to staging for testing. Now PII is in staging where multiple people have access. Compliance violation. Better: Anonymize sensitive fields. Generate realistic but fake data.
Anti-pattern: Wiki documents steps to set up an environment. New developer spends 2 days. Better: Automate with scripts or Docker. New developer runs one command.
Good practice: Each environment has different database passwords, API keys. But anti-pattern: Storing them in code. Better: Use a vault or CI/CD secrets. Application loads at runtime.

Design Review Checklist

  • Can developers test changes locally without manual setup?
  • Do test failures appear in less than 10 minutes?
  • Does staging exactly mirror production infrastructure?
  • Is data properly anonymized in non-prod environments?
  • Can you deploy from staging to prod easily?
  • Are secrets different per environment and stored securely?
  • Do all tests pass before promotion to next environment?
  • Is there a clear definition of 'environment ready'?
  • Can you reproduce production issues in staging?
  • Are environment configurations version controlled (except secrets)?

Self-Check Questions

  1. Local Development: Can a new developer set up locally in < 30 minutes?
  2. Feedback Speed: How long between code change and test results?
  3. Staging Parity: Does staging match prod configuration?
  4. Data Safety: Is sensitive data anonymized in non-prod?
  5. Promotion Path: Clear progression from dev to prod?

Next Steps

  1. Define which environments you need (likely: local dev + test + staging + prod)
  2. Automate environment setup (Docker, Infrastructure as Code)
  3. Ensure staging mirrors production
  4. Implement data anonymization for non-prod
  5. Create clear deployment process between environments

References

  1. Humble, J., & Farley, D. (2010). Continuous Delivery. Addison-Wesley.
  2. Docker ↗️
  3. Kubernetes ↗️