Skip to main content

API Deployment

The API is packaged as a Docker image and designed to run on AWS ECS Fargate, though any container runtime works.

Building the Image

cd apps/api
docker build -t charley-api .

Running Locally

docker run -p 3001:3001 --env-file .env charley-api

Pushing to ECR

aws ecr get-login-password --region us-east-1 \
  | docker login --username AWS --password-stdin <account_id>.dkr.ecr.us-east-1.amazonaws.com

docker tag charley-api:latest <account_id>.dkr.ecr.us-east-1.amazonaws.com/charley-api:latest
docker push <account_id>.dkr.ecr.us-east-1.amazonaws.com/charley-api:latest

ECS Fargate

The repository’s CI/CD pipeline (.github/workflows/) handles ECS deployment automatically on merge to main. For manual deployments:
  1. Push the image to ECR (above).
  2. Update the ECS service to use the new image revision:
aws ecs update-service \
  --cluster <cluster_name> \
  --service <service_name> \
  --force-new-deployment

Required IAM Permissions

The ECS task role needs:
  • ses:SendEmail — for transactional email
  • ecr:GetAuthorizationToken, ecr:BatchGetImage — to pull the image

Dashboard Deployment

The dashboard is a Vite-built SPA that can be hosted on any static file host.

Building

cd apps/web
npm run build
The output is in apps/web/dist/.

S3 + CloudFront

# Sync build output to S3
aws s3 sync apps/web/dist/ s3://<bucket_name>/ --delete

# Invalidate CloudFront cache
aws cloudfront create-invalidation \
  --distribution-id <distribution_id> \
  --paths "/*"
Configure the S3 bucket for static website hosting and set up a CloudFront distribution pointing to it. Set the error document to index.html to support React Router client-side routing.

Vercel / Netlify

Both platforms support Vite out of the box:
  1. Set the build command to npm run build.
  2. Set the publish directory to dist.
  3. Add your VITE_* environment variables in the platform’s settings UI.
  4. Configure rewrites so all paths resolve to index.html (for React Router).

CI/CD Pipeline

The repository uses GitHub Actions. The pipeline:
  1. Static checks — TypeScript compilation, ESLint
  2. Unit tests — Vitest
  3. API trace tests — Tusk Drift replay
  4. Deploy — Docker build → ECR push → ECS update (API) + S3 sync + CloudFront invalidation (dashboard)
Deployments to the dev environment are triggered by merges to develop. Production deployments require a PR from develop to main.

Required GitHub Secrets

SecretDescription
AWS_ACCOUNT_IDAWS account ID
AWS_ROLE_ARNIAM role for OIDC federation
ECR_REPOSITORYECR repository name
ECS_CLUSTERECS cluster name
ECS_SERVICEECS service name
S3_BUCKETFrontend S3 bucket name
CLOUDFRONT_DISTRIBUTION_IDCloudFront distribution ID
AUTH0_DOMAINAuth0 tenant domain
DATABASE_RO_URLRead-only database URL
DATABASE_RW_URLRead-write database URL
STRIPE_SECRET_KEYStripe secret key
STRIPE_WEBHOOK_SECRETStripe webhook secret
TUSK_API_KEYTusk Drift API key (for trace tests)