Deployment & DevOps
Deployment is how your code gets from your laptop to real users.
DevOps is the set of practices and tooling that makes that process reliable, repeatable, and observable.
Environments
Section titled “Environments”Most projects use multiple environments:
- Development: your machine
- Staging: production-like testing
- Production: real users
Example:
- Dev uses a local database.
- Staging/Prod use managed Postgres.
CI/CD (Continuous Integration / Continuous Deployment)
Section titled “CI/CD (Continuous Integration / Continuous Deployment)”Automating the process of testing and releasing code.
- CI: automatically run checks when you push code
- CD: automatically deploy after CI succeeds (sometimes with manual approval)
Example: Simple GitHub Actions Pipeline
Section titled “Example: Simple GitHub Actions Pipeline”name: CIon: pull_request: push: branches: [main]
jobs: test: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - uses: oven-sh/setup-bun@v2 - run: bun install - run: bun run buildDeployment Strategies (Common)
Section titled “Deployment Strategies (Common)”- Rolling deploy: replace instances gradually (common default)
- Blue/green: two environments; switch traffic when ready
- Canary: send a small percentage of users to the new version first
Containerization (Docker)
Section titled “Containerization (Docker)”Docker packages your app and everything it needs into a container.
Why it’s useful:
- same runtime everywhere (no “works on my machine”)
- easy to run locally + in CI
Example: Minimal Dockerfile for a Node/Express API
Section titled “Example: Minimal Dockerfile for a Node/Express API”FROM node:20-alpineWORKDIR /app
COPY package.json package-lock.json ./RUN npm ci
COPY . .EXPOSE 3000CMD ["npm", "start"]Example: Docker Compose (App + Database)
Section titled “Example: Docker Compose (App + Database)”services: db: image: postgres:16 environment: POSTGRES_PASSWORD: postgres POSTGRES_DB: app ports: - '5432:5432' api: build: . environment: DATABASE_URL: postgresql://postgres:postgres@db:5432/app ports: - '3000:3000' depends_on: - dbKubernetes (High Level)
Section titled “Kubernetes (High Level)”Kubernetes manages many containers:
- restarts crashed containers
- scales replicas up/down
- exposes services
It’s powerful, but adds complexity. Many teams start with a single VM or managed platform, then move to Kubernetes when needed.
Version Control (Deployment Reality)
Section titled “Version Control (Deployment Reality)”- Git (focus): commits, branches, merges
- GitHub (focus): PRs, reviews, Actions
Mentions:
- GitLab: Git hosting + CI/CD
- Bitbucket: Git hosting (often used with Jira)
- SVN: older centralized version control system
Operations (What Matters in Production)
Section titled “Operations (What Matters in Production)”As systems grow, these topics become important:
- Backups: regular snapshots + restore testing
- Logging: structured logs (JSON)
- Observability: tracing/metrics/logs (e.g., OpenTelemetry)
- Monitoring / Error Tracking: alerts and dashboards (e.g., Sentry)
- Profiling: find performance bottlenecks
- Message brokers: RabbitMQ, Kafka (often used for async workflows)
- Search engines: Algolia, Elasticsearch
Mini Case Studies
Section titled “Mini Case Studies”Case Study 1: From Laptop to Production (Small Team)
Section titled “Case Study 1: From Laptop to Production (Small Team)”- Developer opens a PR.
- CI runs: lint/tests/build.
- Merge to
maintriggers a deploy. - Deploy updates the running app (rolling) and health-checks it.
Typical “first production” setup:
- One VM
- Nginx + your app process manager
- Managed Postgres
Case Study 2: Deploying with Database Migrations
Section titled “Case Study 2: Deploying with Database Migrations”Many backend deploys are really two deploys:
- Schema change (migration)
- Code change (new app version)
Safe approach:
- Deploy a migration that is backward-compatible (e.g., add a nullable column).
- Deploy the new code that starts using it.
- Later, clean up old columns/paths.
This matters because during a rolling deploy, old and new versions can run at the same time.
Case Study 3: Rollback When Something Breaks
Section titled “Case Study 3: Rollback When Something Breaks”If a release breaks production, a common rollback path is:
- Roll back to the previous container/image/version.
- Keep the database compatible (or have a plan for reversing migrations).
Rule of thumb: reversible database migrations are hard; designing migrations to be backward-compatible is usually the safer strategy.