---
title: "2026-07-17 dashboard compute ui components migration and deploy"
description: "Ran PR #248 (Compute Dashboard) locally in mock mode, migrated its frontend to reuse @virdx/ui-components, and drove the build+deploy of dashboard-frontend/dashboard-api images."
image: "https://docs.virdx.dev/img/virdx-social-card.png"
---

> Documentation Index
> Fetch the complete documentation index at: https://docs.virdx.dev/llms.txt
> Use this file to discover all available pages before exploring further.

# 2026-07-17 dashboard compute ui components migration and deploy

## Work Done

Context: virdx/mono PR #248 "feat: Compute Dashboard" (branch `alex.leake/dashboard_compute`)
added a COMPUTE section (Argo workflows, Tekton builds, Coder workspaces) — ~3.6k lines
across dashboard-api (backend: auth, collectors, routers, services, models, mock_data,
tests) and dashboard-frontend.

1. **Ran the features locally without cluster access.** dashboard-api has a full mock mode
   (`DASHBOARD_MOCK=true`): every compute endpoint (`/builds`, `/workflows`, `/coder`) has an
   `if settings.mock:` fast-path returning `mock_data.py`, and `require_user` returns a fake
   `dev.user` (auth fully bypassed). Minimal local stack = dashboard-api (mock) + frontend;
   no vxdata/postgres needed for compute tabs.
2. **UI-components reuse migration.** The compute code rolled its own UI via a _local_
   `apps/dashboard-frontend/src/components/ui/*` shadcn copy (18 files, pre-existing on main),
   NOT the shared `@virdx/ui-components` (56-component superset). Migrated 7 files (StatusBadge,
   BuildTaskDetail, BuildsList, Builds, WorkflowsList, Workflows, AuthStatus) to import Badge/
   Button/Card/Table/Skeleton/Dialog from `@virdx/ui-components/ui`. Committed + pushed
   `7ec5679` to the branch; merged to main via PR #248 (merge `2be32cf`).
3. **Kept ui-components untouched (user pref).** Shared Badge lacks a `success` variant (has
   default/secondary/destructive/outline/ghost/link). First added `success` to the shared
   badge, but user preferred NOT to touch the shared lib from a feature PR — reverted, instead
   tinted a neutral `secondary` pill green via `className='bg-success/10 text-success
dark:bg-success/20'` in StatusBadge. Verified: prod build passes, typecheck/lint clean on
   touched files (2 pre-existing tsc errors in DataSourcePicker/useBenchmarkSeries are unrelated).
4. **Deploy.** dashboard apps deploy by image tag, NOT semver — no version bump needed.
   Manifests `infra_k8s/current/dashboard/{api,frontend}.yaml` pin `:latest` + Keel
   (`keel.sh/trigger: poll`, `@every 5m`, `policy: force`). Builds normally fire from a
   scheduled argo-events poll (`dashboard-poll`) building from `main`. Triggered manual builds
   via `apps/dashboard-{frontend,api}/deployments/build.sh` (Tekton `buildkit-image` PipelineRun,
   revision main, tag latest). First frontend build failed on a transient zot registry push
   flake (`error writing layer blob: unknown: blob upload unknown to registry`) — resubmitted.
   At session end: frontend retry `f72ms` + api `jhvzh` running; Keel rolls pods within ~5 min
   of push.

## Lessons Learned: Pitfalls

- **"API unchanged" trap.** I initially told the user only the frontend needed rebuilding
  because _my refactor commit_ was frontend-only. But the merged PR #248 added ~2100 lines to
  dashboard-api — that image needed rebuilding too. When advising on rollout, scope to the whole
  merged diff (`git diff 731c551 origin/main -- apps/<app>/`), not just your own commit.
- **process-compose TUI dies in background.** `scripts/dashboard-stack-up.sh` in the background
  fails with `open /dev/tty: device not configured`. Pass `-t=false` to run headless. Also the
  full script relaunches vxdata+postgres and collides if a dev already has their own vxdata
  stack up (their `process-compose` REST API defaults to 8080, colliding with dashboard-api).
  For compute-only tryouts, skip the script: run dashboard-api (mock) on a free port + frontend
  with `VITE_DASHBOARD_API_PROXY_TARGET`.
- **`@virdx/ui-components` needs building before the frontend runs.** No `dist/` exists after a
  fresh `bun install`; Vite fails to resolve `@virdx/ui-components/ui`. Run
  `bunx nx build ui-components` first. After editing/rebuilding it, clear `node_modules/.vite`
  and restart the dev server (Vite won't re-optimize a workspace dep's dist automatically).
- **Misleading build-failure snippet.** A pasted "bun install --frozen-lockfile: Failed to
  install 1 package" looked like a lockfile/Dockerfile bug, but reading the actual build-pod
  logs (`kubectl logs <pr>-build-pod -n tekton-builds`) showed install SUCCEEDED (3171 pkgs) and
  the real failure was the zot push. Always read the full build-pod log before diagnosing;
  buildkit step order and retries make single snippets deceptive.

## Lessons Learned: Improvements

- **Add an infrastructure SOP for the dashboard app** covering: (a) local dev — mock mode +
  minimal 2-process launch, the `bunx nx build ui-components` prerequisite, headless
  `dashboard-stack-up.sh -t=false`; (b) rollout — image-tag + Keel + argo-events poll model
  (no version bump), and `deployments/build.sh` for a manual build from main; (c) the known
  transient zot `blob upload unknown to registry` push flake → just resubmit.
- **Document the local-real-auth blocker.** Real Keycloak login locally is blocked because the
  `dashboard` client (`infra_ansible inventories/group_vars/keycloak/keycloak.yaml`) only
  whitelists `https://dashboard.fra.virdx.dev/*` as a redirect URI — no `http://localhost:5173/*`.
  Worth an SOP note so nobody rediscovers this. Also needs `DASHBOARD_TLS_CA_FILE` on macOS and a
  separate `DASHBOARD_CODER_TOKEN` for the Coder card.
- **Convergence debt:** dashboard-frontend has a split-brain UI layer — local `@/components/ui/*`
  copy vs shared `@virdx/ui-components`. Worth a tracked task to migrate the whole app onto the
  shared lib and delete the local copy (this session only did the compute-PR files).

Source: https://docs.virdx.dev/knowledge/inbox/2026-07-17-infrastructure-dashboard-compute-ui-components-deploy/index.mdx
