Add Phase 1I (Deploy pipeline + runbook) implementation plan
This commit is contained in:
@@ -0,0 +1,106 @@
|
||||
# Phase 1I — Deploy pipeline + runbook contracts
|
||||
|
||||
**Parent plan:** `2026-04-14-phase-1-foundation-master.md`, section "1I — Deploy pipeline + runbook contracts"
|
||||
**Date:** 2026-04-14
|
||||
|
||||
---
|
||||
|
||||
## Overview
|
||||
|
||||
This sub-plan delivers the deploy pipeline contracts: Docker images for both build targets (standalone SSR and remote static), health endpoint, graceful shutdown handler, CI workflow template, and an operational runbook.
|
||||
|
||||
## Constraints
|
||||
|
||||
- Do NOT modify `modern.config.ts` (middleware registration is a future integration step)
|
||||
- Health and shutdown modules export factory functions, not auto-registered middleware
|
||||
- Coexist with the existing ASP.NET `Dockerfile` and `Dockerfile.local` (write `Dockerfile.react` and `Dockerfile.remote`)
|
||||
- Do NOT touch `ClientApp/`, ASP.NET files, or `wwwroot/`
|
||||
|
||||
---
|
||||
|
||||
## Tasks
|
||||
|
||||
### Task 1 — `Dockerfile.react` (standalone SSR image)
|
||||
|
||||
**File:** `Dockerfile.react` (repo root)
|
||||
|
||||
Multi-stage build:
|
||||
1. Stage 1 (`deps`): Node 24 base, enable corepack pnpm, copy `package.json` + `pnpm-lock.yaml`, run `pnpm install --frozen-lockfile`
|
||||
2. Stage 2 (`build`): copy `src/`, config files, run `pnpm build:standalone`
|
||||
3. Stage 3 (`runtime`): Node 24 slim, copy `dist/standalone/`, entrypoint `node dist/standalone/index.js`
|
||||
|
||||
**Exit gate:** File exists, valid Dockerfile syntax.
|
||||
|
||||
### Task 2 — `Dockerfile.remote` (nginx static image)
|
||||
|
||||
**File:** `Dockerfile.remote` (repo root)
|
||||
|
||||
Multi-stage build:
|
||||
1. Stage 1 (`deps`): same as Task 1
|
||||
2. Stage 2 (`build`): copy source, run `pnpm build:remote`
|
||||
3. Stage 3 (`runtime`): `nginx:alpine`, copy `dist/remote/` to `/usr/share/nginx/html`, expose port 80
|
||||
|
||||
**Exit gate:** File exists, valid Dockerfile syntax.
|
||||
|
||||
### Task 3 — Health endpoint (`src/server/routes/health.ts`)
|
||||
|
||||
**Files:** `src/server/routes/health.ts`, `src/server/routes/health.test.ts`
|
||||
|
||||
Export `healthMiddleware(options)` factory function that returns an Express-style `(req, res, next)` handler. The middleware:
|
||||
- Pings the upstream API client on each request (with configurable timeout, default 5000ms)
|
||||
- Tracks last successful ping timestamp
|
||||
- Returns 200 `{ status: "ok" }` if last success < 60s ago
|
||||
- Returns 503 `{ status: "degraded", reason: "upstream_unreachable" }` otherwise
|
||||
|
||||
**TDD:** Tests mock ApiClient, verify 200/503 responses, verify timeout behavior.
|
||||
|
||||
**Exit gate:** `pnpm test` passes health tests.
|
||||
|
||||
### Task 4 — Graceful shutdown (`src/server/shutdown.ts`)
|
||||
|
||||
**Files:** `src/server/shutdown.ts`, `src/server/shutdown.test.ts`
|
||||
|
||||
Export `registerGracefulShutdown(options)` factory function that:
|
||||
- Registers a SIGTERM handler
|
||||
- On SIGTERM: calls `server.close()`, waits up to `drainTimeoutMs` (default 30000), flushes logger transport, exits with code 0
|
||||
- If drain times out, force-exits with code 1
|
||||
|
||||
**TDD:** Tests mock `process.on`, `server.close`, `logger` flush; verify shutdown sequence.
|
||||
|
||||
**Exit gate:** `pnpm test` passes shutdown tests.
|
||||
|
||||
### Task 5 — CI deploy workflow (`.github/workflows/deploy.yml`)
|
||||
|
||||
**File:** `.github/workflows/deploy.yml`
|
||||
|
||||
Template workflow triggered on push to `main`:
|
||||
- Checkout, setup Node 24, install pnpm, `pnpm install --frozen-lockfile`
|
||||
- Build both targets (`pnpm build:both`)
|
||||
- Build Docker images (`Dockerfile.react`, `Dockerfile.remote`)
|
||||
- Push to registry (placeholder)
|
||||
- Deploy to testing environment (placeholder)
|
||||
|
||||
**Exit gate:** File exists, valid YAML syntax.
|
||||
|
||||
### Task 6 — Operational runbook (`docs/superpowers/phase-1/runbook.md`)
|
||||
|
||||
**File:** `docs/superpowers/phase-1/runbook.md`
|
||||
|
||||
Covers:
|
||||
1. Incident response decision tree
|
||||
2. Canary rollout procedure
|
||||
3. Rollback procedure (auto + manual)
|
||||
4. Health-check interpretation
|
||||
5. Log query cookbook
|
||||
6. Known-failure playbooks (6 scenarios)
|
||||
|
||||
**Exit gate:** File exists, covers all required sections.
|
||||
|
||||
---
|
||||
|
||||
## Verification
|
||||
|
||||
After all tasks:
|
||||
```bash
|
||||
pnpm typecheck && pnpm lint && pnpm test
|
||||
```
|
||||
Reference in New Issue
Block a user