Deploying directly to production without a staging environment means every untested configuration change, database migration, or third-party integration issue hits live users first. NIST CM-4 requires evaluating the security impact of changes before production; that evaluation requires a representative environment. A staging environment that uses SQLite while production uses PostgreSQL is not representative — subtle query behavior differences and migration incompatibilities only surface at the worst time.
High because skipping a production-equivalent staging environment means integration failures, migration errors, and environment-specific bugs are discovered by users rather than by the team.
Configure a staging environment with matching infrastructure. For Docker Compose projects, use profiles to separate staging and production:
# docker-compose.yml
services:
app-staging:
build: .
environment:
DATABASE_URL: postgres://staging-db:5432/app
profiles: [staging]
app-prod:
build: .
environment:
DATABASE_URL: postgres://prod-db:5432/app
profiles: [prod]
Add a CI/CD step that deploys to staging after tests pass and before the production promotion step. For Vercel users, Preview Deployments already provide this gate — ensure the preview environment variables match production (same DB engine, same third-party service URLs, same feature flags).
ID: deployment-readiness.ci-cd-pipeline.staging-environment
Severity: high
What to look for: Enumerate every relevant item. Look for staging environment configuration in deployment files (vercel.json preview env, netlify.toml preview context, separate staging database, staging DNS, docker-compose staging profile). Check CI/CD workflow for pre-production deployment step. Look for environment variable files (.env.staging, .env.production) or deployment configs that show distinct staging and production targets.
Pass criteria: At least 1 of the following conditions is met. A staging environment exists with the same infrastructure, dependencies, and service configuration as production. Deployments to staging are part of the CI/CD pipeline before production.
Fail criteria: No staging environment exists, or staging is configured differently from production (e.g., staging uses SQLite while production uses PostgreSQL, or staging omits external services).
Skip (N/A) when: The project is not planned for production, or the platform manages staging automatically (e.g., Vercel preview deployments).
Cross-reference: For user-facing accessibility and compliance, the Accessibility Basics audit covers foundational requirements.
Detail on fail: "No staging environment found. Deployments go directly to production." or "Staging environment exists but uses SQLite database while production uses PostgreSQL — infrastructure mismatch."
Remediation: Set up a staging environment that mirrors production. For a Docker project:
# docker-compose.yml with staging profile
services:
app-staging:
build: .
environment:
DATABASE_URL: postgres://staging-db:5432/app
profiles: [staging]
app-prod:
build: .
environment:
DATABASE_URL: postgres://prod-db:5432/app
profiles: [prod]
Then add a CI/CD step to deploy to staging after tests pass:
- run: docker compose --profile staging up -d