Skip to content
advanced Phase 16 · TypeScript Capstone Project

Capstone: Implementation & Deployment

Build and deploy the TypeScript project with CI/CD pipeline.

2h
0 problems
Topic Progress 0%

The CI Pipeline

The CI Pipeline

Every push runs the same gates a broken merge would skip:

name: ci
on: [push, pull_request]
jobs:
  verify:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-node@v4
        with: { node-version: 20, cache: npm }
      - run: npm ci
      - run: npm run lint && npm run typecheck
      - run: npm test -- --coverage
      - run: npm run build

Order matters: cheapest feedback first (lint, tsc --noEmit), then tests, then build. Use npm ci — it installs from the lockfile exactly — and cache the package manager's store so cold runs stay fast. Failing the job on any step is what makes main trustworthy.

Build, Containerize, Release

Build, Containerize, Release

Ship an artifact, not a checkout. A multi-stage Dockerfile keeps dev dependencies out of production:

FROM node:20-slim AS build
WORKDIR /app
COPY package*.json ./
RUN npm ci
COPY . .
RUN npm run build

FROM node:20-slim
WORKDIR /app
ENV NODE_ENV=production
COPY package*.json ./
RUN npm ci --omit=dev
COPY --from=build /app/dist ./dist
CMD ["node", "dist/server.js"]

Deployment runs migrations before switching traffic, then health checks the new version. Tag images by git SHA (app:4f9c2ab) so rollback is retagging to the previous SHA, not rebuilding. Configuration comes from the platform's environment; secrets never enter the image layer.

Production Pitfalls

Production Pitfalls

Secrets in the repo. A leaked key in git history is compromised even after deletion — use platform secret stores, rotate on exposure, and keep .env out of images with .dockerignore.

No health endpoint. Orchestrators route traffic only when /healthz answers 200; report dependency status there (database ping) so half-up instances drain.

Migrations as deploy steps. Running migrate deploy in a pre-deploy job keeps old and new code compatible with the schema — prefer additive migrations so rollback does not need a schema downgrade.

Silent config drift. Validate env with a typed schema at boot and fail fast; missing PORT should crash at startup, not at first request.

Interview: describe your pipeline stages, the rollback path, and where a migration runs relative to the traffic switch.

Quiz

1. Why run migrations before shifting traffic to a new version?

Question 1 options

2. What does the multi-stage Docker build primarily buy you?

Question 2 options

3. Why tag release images with the git SHA?

Question 3 options

Flashcards

Question

Pipeline order

Answer

lint → typecheck (tsc --noEmit) → tests → build; cheapest failure first.

Question

npm ci

Answer

Clean install from the lockfile — required for reproducible CI.

Question

Multi-stage build

Answer

Build in one stage, copy artifacts to a slim runtime stage.

Question

Health check

Answer

GET /healthz returning 200 (with DB status) gates routing during rollout.

Question

Additive migration

Answer

Schema change old code tolerates — lets rollback skip schema downgrade.

Revision Notes

Key Takeaways

  • 1. Ship a built artifact tagged by commit; never deploy from a working tree
  • 2. Fail fast on config at boot instead of at first request
  • 3. Migrations run before traffic, secrets stay out of images

Interview Tips

  • • Describe rollback end to end: previous image tag, migration compatibility, health gate
  • • Say which step catches each class of failure and why that order

Cheat Sheet

lint→typecheck→test→build in CI with npm ci; multi-stage image, SHA tags; migrate deploy pre-traffic; /healthz gates rollout; secrets from platform store.

Continue Learning