Add deployment dashboard docs and artifacts
- Add design doc for Vercel-style deployment dashboard - Add wave-based implementation plan (4 waves, 11 agents) - Add implementation summary artifact - Update CLAUDE.md with CloudBeaver credentials Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
245
.artifacts/2026-02-06_17-30_deployment-dashboard-design.md
Normal file
245
.artifacts/2026-02-06_17-30_deployment-dashboard-design.md
Normal file
@@ -0,0 +1,245 @@
|
||||
# NUC Portal - Deployment Dashboard Design
|
||||
|
||||
**Date:** 2026-02-06 17:30
|
||||
**Context:** Reverse-engineered Vercel deployment dashboard to design similar feature for nuc-portal
|
||||
|
||||
## Task Summary
|
||||
|
||||
**Goal:** Add deployment detail page to nuc-portal
|
||||
- Current: Click row in Deployments tab → expand/collapse logs inline
|
||||
- New: Click row → navigate to `/deployments/[uuid]` dashboard page
|
||||
- Keep: Add explicit expand button for inline log preview
|
||||
|
||||
## Vercel Dashboard Structure (Reference)
|
||||
|
||||
### Page Layout
|
||||
```
|
||||
Breadcrumb: Deployments > [deployment-id]
|
||||
Tabs: Deployment | Logs | Resources | Source | Open Graph
|
||||
Actions: Share | Logs | Visit
|
||||
```
|
||||
|
||||
### Deployment Tab Sections
|
||||
|
||||
**1. Deployment Details Card (Top)**
|
||||
| Left | Right |
|
||||
|------|-------|
|
||||
| Preview screenshot | Created: user + date |
|
||||
| | Status: Ready + "Latest" badge |
|
||||
| | Duration: 43s + "43d ago" |
|
||||
| | Environment: Production + "Current" |
|
||||
| | Domains: list with "+N" overflow |
|
||||
| | Source: branch + commit hash + message |
|
||||
|
||||
**2. Collapsible Sections:**
|
||||
|
||||
| Section | Content |
|
||||
|---------|---------|
|
||||
| **Deployment Settings** | Recommendations cards, Build Settings (concurrent builds, machine specs, prioritize prod), Runtime Settings (fluid compute, function CPU, Node version, protections) |
|
||||
| **Build Logs** | Header: line count, warnings, search. Body: timestamped log lines, warnings highlighted yellow |
|
||||
| **Deployment Summary** | Framework badge, Edge Middleware count, Static Assets (filterable by type), Functions, ISR Functions, Cron Jobs |
|
||||
| **Deployment Checks** | External check integrations or "No checks configured" |
|
||||
| **Assigning Custom Domains** | Domain list with status checkmarks and manage links |
|
||||
|
||||
**3. Bottom Cards (4-column grid):**
|
||||
- Runtime Logs | Observability | Speed Insights | BotID
|
||||
|
||||
---
|
||||
|
||||
## Coolify Data Available
|
||||
|
||||
### From Deployment Table
|
||||
```typescript
|
||||
interface CoolifyDeployment {
|
||||
deployment_uuid: string;
|
||||
application_id: string;
|
||||
application_name: string;
|
||||
server_name: string;
|
||||
status: 'finished' | 'error' | 'in_progress' | 'queued' | 'cancelled';
|
||||
commit: string; // SHA
|
||||
commit_message: string; // Full message
|
||||
is_webhook: boolean;
|
||||
is_api: boolean;
|
||||
force_rebuild: boolean;
|
||||
rollback: boolean;
|
||||
created_at: string;
|
||||
updated_at: string;
|
||||
finished_at: string | null;
|
||||
logs: DeploymentLog[]; // JSON array with timestamps
|
||||
deployment_url: string; // Coolify UI link
|
||||
}
|
||||
```
|
||||
|
||||
### From Application Table
|
||||
```typescript
|
||||
interface CoolifyApp {
|
||||
uuid: string;
|
||||
name: string;
|
||||
fqdn: string; // e.g., "http://nuc.lan"
|
||||
status: string; // e.g., "running:unknown"
|
||||
git_repository: string;
|
||||
git_branch: string;
|
||||
build_pack: string; // nixpacks, dockerfile, etc.
|
||||
ports_exposes: string;
|
||||
created_at: string;
|
||||
updated_at: string;
|
||||
}
|
||||
```
|
||||
|
||||
### Direct Database Query (via tinker)
|
||||
```bash
|
||||
ssh nuc "docker exec coolify php artisan tinker --execute=\"
|
||||
use App\\\\Models\\\\Application;
|
||||
use App\\\\Models\\\\ApplicationDeploymentQueue;
|
||||
\\\$app = Application::where('uuid', '<uuid>')->first();
|
||||
\\\$d = ApplicationDeploymentQueue::where('application_id', \\\$app->id)->latest()->first();
|
||||
echo json_encode(\\\$d->toArray(), JSON_PRETTY_PRINT);
|
||||
\""
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Gap Analysis
|
||||
|
||||
### What Coolify Provides (Direct Mapping)
|
||||
- Deployment UUID, status, timestamps, duration (computed)
|
||||
- Git branch, commit SHA, commit message
|
||||
- Build logs with timestamps
|
||||
- App name, FQDN/domains, build pack, ports
|
||||
- Webhook/API trigger info
|
||||
|
||||
### Gaps - Ranked by Priority
|
||||
|
||||
**Tier 1 - High Impact, Easy**
|
||||
1. **Healthcheck Status** - Docker API: `docker inspect --format='{{.State.Health.Status}}'`
|
||||
2. **Container Metrics** - Docker stats: CPU%, Memory usage
|
||||
3. **Environment Label** - Parse from Coolify project/environment structure
|
||||
|
||||
**Tier 2 - High Impact, Medium Effort**
|
||||
4. **Preview Screenshot** - Playwright screenshot service triggered on deploy success
|
||||
5. **Runtime Logs Link** - Deep link to Dozzle: `http://dozzle.nuc.lan/container/<name>`
|
||||
6. **Rollback Button** - Coolify API supports rollback
|
||||
|
||||
**Tier 3 - Nice to Have**
|
||||
7. **Build Cache Status** - Parse "Restored build cache" from logs
|
||||
8. **Image Size** - `docker images --format` after build
|
||||
9. **Uptime Since Deploy** - Container start time from Docker
|
||||
|
||||
**Tier 4 - Future**
|
||||
10. **Response Time** - Uptime Kuma integration
|
||||
11. **Error Rate** - Log parsing or APM
|
||||
12. **Git Diff Link** - Construct Gitea compare URL
|
||||
|
||||
---
|
||||
|
||||
## Proposed Implementation
|
||||
|
||||
### Route Structure
|
||||
```
|
||||
/deployments/[uuid] → Deployment dashboard page
|
||||
```
|
||||
|
||||
### UI Changes to Deployments Table
|
||||
- Add expand/collapse button (chevron icon) on each row
|
||||
- Row click → navigate to dashboard
|
||||
- Button click → expand logs inline (current behavior)
|
||||
|
||||
### Dashboard Page Sections (Simplified for Coolify)
|
||||
|
||||
```
|
||||
┌─────────────────────────────────────────────────────────┐
|
||||
│ ← Back to Deployments rok0w0gg [Actions] │
|
||||
├─────────────────────────────────────────────────────────┤
|
||||
│ │
|
||||
│ ┌──────────┐ Created: alezmad · Feb 6, 2026 │
|
||||
│ │ Preview │ Status: ● Ready Health: ● Healthy │
|
||||
│ │ or Icon │ Duration: 2m 51s · 2h ago │
|
||||
│ └──────────┘ Environment: production │
|
||||
│ │
|
||||
│ Domains: http://nuc.lan │
|
||||
│ Source: main · f7c57ca · "Use domain-based URLs..." │
|
||||
├─────────────────────────────────────────────────────────┤
|
||||
│ ▼ Build Logs 43s ⚠2 ✓ │
|
||||
│ [Timestamped log content...] │
|
||||
├─────────────────────────────────────────────────────────┤
|
||||
│ ▶ Container Info │
|
||||
│ Build: nixpacks · Ports: 3000 │
|
||||
│ CPU: 2.3% · Memory: 156MB │
|
||||
├─────────────────────────────────────────────────────────┤
|
||||
│ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │
|
||||
│ │ Runtime │ │ Redeploy │ │ Rollback │ │
|
||||
│ │ Logs → │ │ │ │ │ │
|
||||
│ └─────────────┘ └─────────────┘ └─────────────┘ │
|
||||
└─────────────────────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
### API Endpoints Needed
|
||||
|
||||
```typescript
|
||||
// Existing (nuc-portal)
|
||||
GET /api/deployments // List all
|
||||
GET /api/deployments/[uuid] // Get one with logs
|
||||
|
||||
// New endpoints
|
||||
GET /api/deployments/[uuid]/health // Container healthcheck
|
||||
GET /api/deployments/[uuid]/stats // CPU/Memory from docker stats
|
||||
POST /api/deployments/[uuid]/rollback // Trigger rollback
|
||||
```
|
||||
|
||||
### Docker Commands for New Features
|
||||
|
||||
```bash
|
||||
# Healthcheck status
|
||||
docker inspect --format='{{.State.Health.Status}}' <container>
|
||||
|
||||
# Container stats (one-shot)
|
||||
docker stats --no-stream --format='{{.CPUPerc}},{{.MemUsage}}' <container>
|
||||
|
||||
# Container start time (for uptime)
|
||||
docker inspect --format='{{.State.StartedAt}}' <container>
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Files to Modify
|
||||
|
||||
```
|
||||
nuc-portal/
|
||||
├── src/app/deployments/[uuid]/page.tsx # NEW - Dashboard page
|
||||
├── src/components/DeploymentsTable.tsx # Add expand button, row click nav
|
||||
├── src/components/DeploymentDashboard.tsx # NEW - Dashboard component
|
||||
├── src/app/api/deployments/[uuid]/
|
||||
│ ├── route.ts # Existing - add more fields
|
||||
│ ├── health/route.ts # NEW - healthcheck endpoint
|
||||
│ └── stats/route.ts # NEW - container stats
|
||||
└── src/lib/docker.ts # NEW - Docker API helpers
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Implementation Order
|
||||
|
||||
### Phase 1: Basic Dashboard (MVP)
|
||||
1. Create `/deployments/[uuid]` route and page
|
||||
2. Add expand button to table rows
|
||||
3. Make row click navigate to dashboard
|
||||
4. Display existing deployment data in dashboard layout
|
||||
|
||||
### Phase 2: Enhanced Data (Tier 1 gaps)
|
||||
5. Add healthcheck status endpoint
|
||||
6. Add container metrics endpoint
|
||||
7. Add environment label parsing
|
||||
|
||||
### Phase 3: Actions & Links (Tier 2 gaps)
|
||||
8. Add Dozzle deep link
|
||||
9. Add rollback button
|
||||
10. (Optional) Screenshot service
|
||||
|
||||
---
|
||||
|
||||
## Related Documentation
|
||||
|
||||
- Coolify API: `http://192.168.1.3:8000/api/v1/`
|
||||
- Existing nuc-portal code: `/Users/agutierrez/Desktop/nuc/nuc-portal/`
|
||||
- Deployment types: `nuc-portal/src/lib/deployments.ts`
|
||||
- Coolify helpers: `nuc-portal/src/lib/coolify.ts`
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,173 @@
|
||||
# Deployment Dashboard Implementation
|
||||
|
||||
**Date:** 2026-02-06 19:30
|
||||
**Project:** nuc-portal
|
||||
**Context:** Implemented Vercel-style deployment detail pages with parallel wave-based execution
|
||||
|
||||
---
|
||||
|
||||
## Overview
|
||||
|
||||
Added a comprehensive deployment dashboard to nuc-portal that displays detailed information about individual deployments, including real-time container health, stats, build logs, and quick action buttons.
|
||||
|
||||
## Architecture
|
||||
|
||||
```
|
||||
User Flow:
|
||||
Deployments Tab → Click Row → /deployments/[uuid] (Dashboard)
|
||||
→ Click Chevron → Expand Logs Inline (preserved)
|
||||
|
||||
API Flow:
|
||||
Dashboard Page
|
||||
├── /api/deployments/[uuid] → Deployment details
|
||||
├── /api/deployments/[uuid]/health → Container health (SWR 10s)
|
||||
├── /api/deployments/[uuid]/stats → Container stats (SWR 10s)
|
||||
└── /api/deployments/[uuid]/redeploy → Trigger new deployment
|
||||
```
|
||||
|
||||
## Files Created
|
||||
|
||||
| File | Purpose | Lines |
|
||||
|------|---------|-------|
|
||||
| `src/app/deployments/[uuid]/page.tsx` | Dynamic route for deployment details | ~150 |
|
||||
| `src/components/DeploymentDashboard.tsx` | Main dashboard component with tabs | ~800 |
|
||||
| `src/components/DeploymentSkeleton.tsx` | Loading, error, empty state components | ~200 |
|
||||
| `src/lib/docker.ts` | Docker API helpers via SSH | ~150 |
|
||||
| `src/app/api/deployments/[uuid]/health/route.ts` | Container health endpoint | ~50 |
|
||||
| `src/app/api/deployments/[uuid]/stats/route.ts` | Container stats endpoint | ~60 |
|
||||
| `src/app/api/deployments/[uuid]/redeploy/route.ts` | Redeploy trigger endpoint | ~50 |
|
||||
|
||||
## Files Modified
|
||||
|
||||
| File | Changes |
|
||||
|------|---------|
|
||||
| `src/components/DeploymentsTable.tsx` | Added expand button, row click navigation |
|
||||
| `src/components/Icons.tsx` | Added missing icons (user, clock, share, etc.) |
|
||||
| `src/components/index.ts` | Exported new components |
|
||||
|
||||
## Features
|
||||
|
||||
### Dashboard Tabs
|
||||
1. **Deployment** - Main view with metadata, preview, and collapsible sections
|
||||
2. **Logs** - Build logs with warning highlighting
|
||||
3. **Resources** - CPU, Memory, Network I/O, Block I/O
|
||||
4. **Source** - Git branch, commit, message
|
||||
|
||||
### Real-Time Data (SWR)
|
||||
- Health status polling every 10 seconds
|
||||
- Container stats polling every 10 seconds
|
||||
- Auto-refresh with loading states
|
||||
|
||||
### Action Cards
|
||||
| Card | Action | URL |
|
||||
|------|--------|-----|
|
||||
| Runtime Logs | Opens Dozzle | `http://192.168.1.3:9999/container/{name}` |
|
||||
| Coolify | Opens Coolify deployment | `http://coolify.nuc.lan:8000/...` |
|
||||
| Visit Site | Opens app FQDN | `{deployment.fqdn}` |
|
||||
| Redeploy | Triggers new deployment | POST `/api/.../redeploy` |
|
||||
|
||||
### Edge Cases Handled
|
||||
- `in_progress` - Shows "Building..." with amber banner
|
||||
- `error` - Shows error banner, auto-expands logs
|
||||
- `cancelled` - Shows grey cancelled state
|
||||
- Missing container - Graceful degradation with messages
|
||||
- Missing git info - Shows "—" instead of crashing
|
||||
- Null duration - Shows "In progress..."
|
||||
|
||||
### Loading & Error States
|
||||
- `DeploymentSkeleton` - Animated loading skeleton
|
||||
- `DeploymentError` - Error with retry button
|
||||
- `DeploymentEmpty` - Empty state for edge cases
|
||||
|
||||
## Docker API Helpers
|
||||
|
||||
`src/lib/docker.ts` provides:
|
||||
|
||||
```typescript
|
||||
// Execute command via SSH to NUC
|
||||
sshExec(command: string): Promise<string | null>
|
||||
|
||||
// Get container health status
|
||||
getContainerHealth(containerName: string): Promise<'healthy' | 'unhealthy' | 'starting' | 'none' | null>
|
||||
|
||||
// Get container resource stats
|
||||
getContainerStats(containerName: string): Promise<{
|
||||
cpuPercent: number;
|
||||
memoryUsage: string;
|
||||
memoryLimit: string;
|
||||
memoryPercent: number;
|
||||
netIO: { rx: string; tx: string };
|
||||
blockIO: { read: string; write: string };
|
||||
} | null>
|
||||
|
||||
// Get container uptime
|
||||
getContainerUptime(containerName: string): Promise<{
|
||||
startedAt: string;
|
||||
seconds: number;
|
||||
formatted: string;
|
||||
} | null>
|
||||
|
||||
// Find container by app name or UUID
|
||||
findContainerByAppName(appName: string): Promise<string | null>
|
||||
findContainerByUuid(appUuid: string): Promise<string | null>
|
||||
```
|
||||
|
||||
## Implementation Method
|
||||
|
||||
Used parallel wave-based execution with 11 total agents:
|
||||
|
||||
| Wave | Tasks | Agents | Duration |
|
||||
|------|-------|--------|----------|
|
||||
| Wave 1 | Route, Docker helpers, Table UI | 3 parallel | ~3.5 min |
|
||||
| Wave 2 | Dashboard, Health API, Stats API, Navigation | 4 parallel | ~4.5 min |
|
||||
| Wave 3 | Data integration, Links, Redeploy | 3 parallel | ~5 min |
|
||||
| Wave 4 | Loading states, Edge cases | 2 parallel | ~3 min |
|
||||
|
||||
**Total implementation time:** ~16 minutes
|
||||
|
||||
## Testing
|
||||
|
||||
```bash
|
||||
# Start dev server
|
||||
cd /Users/agutierrez/Desktop/nuc/nuc-portal
|
||||
npm run dev
|
||||
|
||||
# Get a deployment UUID
|
||||
curl http://localhost:3000/api/deployments | jq '.[0].deployment_uuid'
|
||||
|
||||
# Test dashboard page
|
||||
open http://localhost:3000/deployments/<uuid>
|
||||
|
||||
# Test API endpoints
|
||||
curl http://localhost:3000/api/deployments/<uuid>/health | jq
|
||||
curl http://localhost:3000/api/deployments/<uuid>/stats | jq
|
||||
curl -X POST http://localhost:3000/api/deployments/<uuid>/redeploy | jq
|
||||
```
|
||||
|
||||
## Dependencies Added
|
||||
|
||||
```json
|
||||
{
|
||||
"swr": "^2.x" // For data fetching with auto-refresh
|
||||
}
|
||||
```
|
||||
|
||||
## URLs Configuration
|
||||
|
||||
Per user request, Coolify URLs use domain name:
|
||||
- ✅ `http://coolify.nuc.lan:8000` (not IP)
|
||||
- Dozzle still uses IP (no domain configured): `http://192.168.1.3:9999`
|
||||
|
||||
## Screenshots
|
||||
|
||||
Dashboard follows Vercel's deployment page design:
|
||||
- Header with app icon, metadata grid
|
||||
- Collapsible sections (Settings, Build Logs, Container Stats, Summary)
|
||||
- Action cards grid at bottom
|
||||
- Tab navigation (Deployment, Logs, Resources, Source)
|
||||
|
||||
## Related
|
||||
|
||||
- Design doc: `.artifacts/2026-02-06_17-30_deployment-dashboard-design.md`
|
||||
- Implementation plan: `.artifacts/2026-02-06_18-00_deployment-dashboard-implementation-plan.md`
|
||||
- nuc-portal repo: `/Users/agutierrez/Desktop/nuc/nuc-portal/`
|
||||
Reference in New Issue
Block a user