Files
nuc/.artifacts/2026-02-06_20-00_minio-s3-storage-setup.md
Alejandro Gutiérrez f2208e660c Add MinIO S3 storage setup artifact
Documents nuc-portal S3 configuration for deployment previews

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-06 18:11:56 +01:00

3.5 KiB

MinIO S3 Storage Setup for nuc-portal

Date: 2026-02-06 20:00 Context: Added S3-compatible storage for deployment preview screenshots


MinIO Configuration

Access Details

Property Value
API Endpoint http://192.168.1.3:9000
Console http://192.168.1.3:9001
Root User minioadmin
Root Password minioadmin

nuc-portal Service Account

Property Value
Access Key nuc-portal
Secret Key YpVhIltqY6itWQXHWbEzJ82O9Qr3viR5
Policy readwrite
Bucket nuc-portal-previews

Port Forwarder

MinIO container wasn't exposed on host. Created port forwarder:

# Container: minio-port-fwd
# Forwards: 9000 (API) and 9001 (Console)
docker run -d --name minio-port-fwd \
  --network xwowg8kswwsocssgocs8ss40 \
  -p 9000:9000 \
  -p 9001:9001 \
  alpine/socat \
  TCP-LISTEN:9000,fork,reuseaddr TCP-CONNECT:minio-xwowg8kswwsocssgocs8ss40:9000

Environment Variables

Added to /Users/agutierrez/Desktop/nuc/nuc-portal/.env.local:

# MinIO / S3 Storage (for deployment previews)
S3_ENDPOINT=http://192.168.1.3:9000
S3_ACCESS_KEY=nuc-portal
S3_SECRET_KEY=YpVhIltqY6itWQXHWbEzJ82O9Qr3viR5
S3_BUCKET=nuc-portal-previews
S3_REGION=us-east-1

Files Created

src/lib/s3.ts

S3 client helper with functions:

Function Purpose
uploadFile(key, body, contentType) Upload any file
uploadPreviewScreenshot(appUuid, deploymentUuid, buffer) Upload deployment preview
getPresignedUrl(key, expiresIn) Get signed URL for reading
getPreviewUrl(appUuid, deploymentUuid) Get preview presigned URL
fileExists(key) Check if file exists
previewExists(appUuid, deploymentUuid) Check if preview exists
deleteFile(key) Delete a file
getFile(key) Download file as Buffer

src/app/api/deployments/[uuid]/preview/route.ts

API endpoint that:

  • Checks if preview exists in S3
  • Returns presigned URL (valid 1 hour) if exists
  • Returns { exists: false } with hint if not

Dashboard Integration

Updated DeploymentDashboard.tsx:

  • Added SWR hook for preview fetching
  • Shows loading spinner while fetching
  • Displays image if preview exists
  • Falls back to placeholder if not

Storage Structure

nuc-portal-previews/
└── previews/
    └── {app-uuid}/
        └── {deployment-uuid}.png

Dependencies Added

{
  "@aws-sdk/client-s3": "^3.x",
  "@aws-sdk/s3-request-presigner": "^3.x"
}

Next Steps

To capture screenshots automatically:

  1. Add post-deployment hook in Coolify
  2. Use Playwright (playwriter-nuc-01) to take screenshot
  3. Upload to MinIO via uploadPreviewScreenshot()

Manual capture example:

// Using Playwright to capture screenshot
const screenshot = await page.screenshot({ type: 'png' });
await uploadPreviewScreenshot(appUuid, deploymentUuid, screenshot);

Verification

# Test MinIO health
curl http://192.168.1.3:9000/minio/health/live

# List buckets (via mc)
ssh nuc 'docker run --rm --network host --entrypoint /bin/sh minio/mc -c "
mc alias set m http://localhost:9000 nuc-portal YpVhIltqY6itWQXHWbEzJ82O9Qr3viR5
mc ls m/
"'

# Test preview API
curl http://localhost:3000/api/deployments/<uuid>/preview

  • MinIO container: minio-xwowg8kswwsocssgocs8ss40
  • Port forwarder: minio-port-fwd
  • Implementation: .artifacts/2026-02-06_19-30_deployment-dashboard-implementation.md