DEV Community

HamzaNab-Dev
HamzaNab-Dev

Posted on

Building a Full-Stack AI App on Vercel + AWS ECS in One Hackathon — ChatScroll

For the AWS H0 Hackathon, I built and deployed ChatScroll
— a full-stack AI knowledge management app — using Next.js
on Vercel for the frontend and ASP.NET Core 9 on AWS ECS
Fargate for the backend. Here's how the deployment
architecture works and what I learned.

The Stack

Frontend: Next.js 14 App Router + TypeScript +
Tailwind CSS deployed on Vercel

Backend: ASP.NET Core 9 API running on AWS ECS Fargate

  • Containerized with Docker
  • Images stored in Amazon ECR
  • Deployed automatically via GitHub Actions

Databases:

  • Amazon Aurora PostgreSQL (pgvector, ltree, tsvector)
  • Amazon DynamoDB (chat messages, TTL)

Auth: AWS Cognito with JWT verification

The CI/CD Pipeline

Every push to master triggers this automated pipeline:

git push → GitHub Actions → docker build → ECR push → ECS deploy → ✅ live
Enter fullscreen mode Exit fullscreen mode

The key insight I learned: --force-new-deployment alone
does NOT pick up new Docker images. It just restarts the
service using the existing task definition.

The correct approach:

  1. Fetch current task definition via describe-task-definition
  2. Update the container image to the new SHA-tagged ECR image
  3. Register a NEW task definition revision
  4. Pass the new revision ARN explicitly to update-service
NEW_TASK_DEF=$(echo "$TASK_DEF" | jq \
  --arg IMAGE "$ECR_REPO:${{ github.sha }}" \
  '.containerDefinitions[0].image = $IMAGE | 
   del(.taskDefinitionArn, .revision, .status, 
   .requiresAttributes, .placementConstraints, 
   .compatibilities, .registeredAt, .registeredBy)')

NEW_REVISION=$(aws ecs register-task-definition \
  --cli-input-json "$NEW_TASK_DEF" \
  --query 'taskDefinition.taskDefinitionArn' \
  --output text)

aws ecs update-service \
  --cluster default \
  --service chatscroll-api \
  --task-definition $NEW_REVISION \
  --force-new-deployment
Enter fullscreen mode Exit fullscreen mode

This ensures every deploy runs the exact new image.

Vercel + AWS Together

The combination of Vercel and AWS works beautifully:

  • Vercel handles frontend deployment, CDN, and edge caching — zero configuration needed
  • AWS ECS handles the backend with full control over the runtime environment
  • Environment variables in both Vercel and ECS task definitions keep secrets secure

The frontend on Vercel calls the backend on ECS via
REST API — clean separation of concerns with each
platform doing what it does best.

Anonymous → Authenticated Migration

One interesting challenge: users can chat and save
Scrolls before signing up. When they create an account,
their anonymous data needs to migrate to their new
Cognito identity.

I built a POST /api/users/me/migrate-anonymous endpoint:

  • Requires valid JWT (authenticated)
  • Accepts the anonymous UUID from localStorage
  • Runs 4 UPDATE statements atomically in Aurora
  • Removes the anonymous user row after migration
  • Frontend calls it once on first login then never again

This means users never lose their data when they sign up.

What I Built in One Hackathon

  • Full CI/CD pipeline from git push to live ECS deployment
  • Dual database architecture (Aurora + DynamoDB)
  • Semantic search with pgvector and 3072-dim embeddings
  • AWS Cognito authentication with anonymous migration
  • Study Mode flashcards, scroll sharing, semantic search

Try it: https://chatscroll.vercel.app
Architecture: https://chatscroll.vercel.app/aws-showcase

I created this content for the purposes of entering
the AWS H0 Hackathon.

H0Hackathon #AWS #ECS #Vercel #Docker #Aurora #DynamoDB #H0Hackathon

Top comments (0)