Most 5-engineer teams do not need a dedicated platform engineer or a custom pipeline DSL. They need a setup that is boring, reliable, and ships code safely to production every day. Here is the stack we set up by default on new client engagements.
The shape of the pipeline
- Push to a branch → CI runs lint, typecheck, unit tests.
- Open a PR → add integration tests, build Docker image, run security scans.
- Merge to
main→ deploy to staging automatically. - Tag a release → deploy to production with manual approval.
That's it. Four stages, each doing one thing well.
Tools we use
- GitHub Actions — native to the source code, generous free tier, easy secrets management.
- Docker + multi-stage builds — smaller images, better caching, consistent runtime.
- GHCR or ECR — for container registry. GHCR is free and good enough for most.
- Kubernetes (EKS/GKE) or Fly.io/Railway — depending on scale. Do not start with K8s unless you need it.
- Terraform — for infra. Even if it is 200 lines, Terraform beats click-ops.
Boring tools compound. Flashy tools decay.
Speed matters — keep CI under 5 minutes
A slow CI kills developer velocity. Our targets:
- Unit tests: under 2 minutes
- Full CI on PR: under 5 minutes
- Deploy to staging: under 3 minutes
To get there: cache node_modules/pip deps, run tests in parallel shards, and do not rebuild what has not changed.
Safety rails
- Branch protection: require status checks and one review.
- Auto-revert: if staging smoke tests fail, the pipeline rolls back.
- Feature flags (via LaunchDarkly, Unleash, or your own table) so risky features can ship dark.
- Database migrations: always additive first, backfill, then drop later.
Observability from day one
Ship logs to a log aggregator (we like Grafana Loki or Datadog), metrics to Prometheus, and error tracking to Sentry. Wire up alerting on the three things that actually matter: error rate, latency, and deployment failures. Add more alerts only after you have ignored a notification twice.
What we skip on purpose
- Complex canary deployments (staging + feature flags cover 90% of the value).
- Multi-cloud abstractions (pick one cloud and commit).
- A dedicated CI tool separate from the source host (GitHub Actions is plenty).
This setup takes about a week to stand up on a new project and saves months of pain down the road. Keep it boring.
← Back to blog