Captures the full output of autodev existing-code Phase A through Step 4 (Code Testability Revision) for the Azaion UI workspace: - Step 1 Document: _docs/02_document/ (FINAL_report, architecture, glossary, components/, modules/, diagrams/, system-flows, module-layout) plus _docs/00_problem/ + _docs/01_solution/ + _docs/legacy/ + _docs/how_to_test + README. - Step 2 Architecture Baseline: architecture_compliance_baseline.md. - Step 3 Test Spec: _docs/02_document/tests/ (environment, test-data, blackbox/performance/resilience/security/ resource-limit tests, traceability-matrix), enum_spec_snapshot, expected_results/results_report.md (98 rows), plus the run-tests.sh + run-performance-tests.sh runners. - Step 4 Code Testability Revision: 01-testability-refactoring/ run dir (list-of-changes C01-C07, deferred_to_refactor, analysis/research_findings + refactoring_roadmap) and the 7 child task specs AZ-448..AZ-454 under _docs/02_tasks/todo/ plus _dependencies_table.md. - _docs/_autodev_state.md pins the cursor at Step 4 / refactor Phase 4 entry so /autodev resumes cleanly. Epic AZ-447 (UI testability gates) tracks the 7 child tasks that will land in subsequent commits. Co-authored-by: Cursor <cursoragent@cursor.com>
3.5 KiB
Azaion UI — Containerization
Synthesis output of
/documentStep 3d (containerization). Derived fromDockerfile,nginx.conf, and00_discovery.md§3.
1. Image
Multi-stage build (Dockerfile):
| Stage | Base image | Role |
|---|---|---|
| 1 (builder) | oven/bun:1.3.11-alpine |
bun install --frozen-lockfile + bun run build (= tsc -b && vite build) → dist/ |
| 2 (runtime) | nginx:alpine |
Serves /usr/share/nginx/html (dist/); listens on :80 |
Why this shape:
- Bun gives a fast install + build vs. npm/yarn/pnpm.
- nginx alpine is a sub-25 MB runtime that already has reverse-proxy routing for
/api. - No Node runtime in production → smaller attack surface, faster startup, lower memory.
Image labels (OCI, set by Woodpecker CI):
org.opencontainers.image.revision = $CI_COMMIT_SHAorg.opencontainers.image.created = $CI_BUILD_CREATEDorg.opencontainers.image.source = <repo url>
Environment:
AZAION_REVISION = $CI_COMMIT_SHA— accessible at runtime for diagnostics.- No other env vars consumed at runtime by the SPA bundle (the bundle is fully static).
2. nginx routing (nginx.conf)
The image's nginx config strips /api/<service>/ and reverse-proxies to the matching suite service inside the container network.
| Public path | Upstream (intra-cluster) | Service |
|---|---|---|
/api/annotations/ |
http://annotations:8080/ |
annotations/ |
/api/flights/ |
http://flights:8080/ |
flights/ |
/api/admin/ |
http://admin:8080/ |
admin/ |
/api/resource/ |
http://resource:8080/ |
resource/ |
/api/detect/ |
http://detect:8080/ |
detect/ |
/api/loader/ |
http://loader:8080/ |
loader/ |
/api/gps-denied-desktop/ |
http://gps-denied-desktop:8080/ |
gps-denied-desktop/ |
/api/gps-denied-onboard/ |
http://gps-denied-onboard:8080/ |
gps-denied-onboard/ |
/api/autopilot/ |
http://autopilot:8080/ |
autopilot/ |
/ (any other path) |
static fallback to /index.html (SPA routing) |
— |
Body size cap: client_max_body_size 500M — tlog + video uploads in GPS-Denied Test Mode and large image uploads in Annotations both ride this limit.
Headers passed to upstream: standard Host, X-Real-IP, X-Forwarded-For, X-Forwarded-Proto (assumed — verify in nginx.conf).
SSE handling: proxy_buffering off MUST be set on /api/detect/ and any other path that streams (Step 4 verification — confirm in nginx.conf).
3. Resource sizing (recommended, not enforced)
| Resource | Recommendation | Rationale |
|---|---|---|
| CPU | 100 m (0.1 vCPU) | nginx is near-idle; 99 % of work is suite services |
| Memory | 32 Mi | nginx + ~5 MB of static assets |
| Storage | ephemeral 50 Mi | bundle is sub-5 MB gzipped today; some headroom |
| Replicas | 1+ | trivially horizontal; HA only matters if the ingress sits in front |
Bundle size budget: vite build output should stay under ~2 MB gzipped initial JS. Currently chart.js and leaflet are the dominant chunks; AltitudeChart is a lazy-load candidate (finding in 05_flights).
4. Health checks
Today: none.
Recommended (Step 4 / Step 6 surface):
- Liveness:
GET /index.html → 200 - Readiness: same (the SPA has no warm-up)
- Container health:
wget --spider -q http://localhost/index.html
The suite-level orchestrator (parent suite docker-compose / k8s) is expected to handle ingress health-checking; individual UI replicas don't need their own.