Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/subratomandal/dyeink/llms.txt

Use this file to discover all available pages before exploring further.

Overview

This guide covers the complete migration from Supabase to a modern, scalable stack:
  • Backend: Fastify + MongoDB
  • Authentication: Auth0
  • Storage: Cloudflare R2
  • Deployment: Cloudflare Workers
This migration improves performance, reduces vendor lock-in, and provides more flexible scaling options.

Prerequisites

Before starting, ensure you have:
  • Node.js 18+ installed
  • MongoDB Atlas account (free tier or $50 credit)
  • Auth0 account (free tier: 7,500 monthly active users)
  • Cloudflare account (free tier: 100K requests/day)
  • Vercel account (for domain management)
This migration involves changing your entire backend infrastructure. Test thoroughly in a development environment before migrating production data.

Step 1: MongoDB setup

Create MongoDB Atlas cluster

1

Create a project

  1. Go to MongoDB Atlas
  2. Create a new project: dyeink
2

Deploy a cluster

Deploy a free cluster (M0) or use your $50 credit for a paid tier
3

Create database user

Create a database user with read/write access to the dyeink database
4

Configure network access

  • For development: Add your current IP
  • For production: Add 0.0.0.0/0 (allow from anywhere)
Cloudflare Workers require 0.0.0.0/0 access as they don’t have fixed IPs.

Enable MongoDB Data API

For Cloudflare Workers deployment, you need the Data API:
1

Navigate to Data API

Go to Data Services > Data API
2

Enable and configure

  1. Enable the Data API
  2. Copy the App ID
  3. Generate an API Key
  4. Note the Data API URL format:
https://data.mongodb-api.com/app/{APP_ID}/endpoint/data/v1

Get connection string

Your MongoDB connection string format:
mongodb+srv://<username>:<password>@<cluster>.mongodb.net/dyeink?retryWrites=true&w=majority
Save this connection string securely - you’ll need it for backend configuration.

Step 2: Auth0 setup

Create Auth0 application

1

Create SPA application

  1. Go to Auth0 Dashboard
  2. Create a new Single Page Application
  3. Name it “Dyeink”
2

Configure application settings

Set the following URLs:
  • Allowed Callback URLs:
    http://localhost:5173, https://yourdomain.com
    
  • Allowed Logout URLs:
    http://localhost:5173, https://yourdomain.com
    
  • Allowed Web Origins:
    http://localhost:5173, https://yourdomain.com
    

Create Auth0 API

1

Create the API

  1. Go to APIs > Create API
  2. Name: DyeInk API
  3. Identifier: https://api.dyeink.com (this is your audience)
  4. Signing Algorithm: RS256

Configure social connections

1

Enable GitHub login

  1. Go to Authentication > Social
  2. Enable GitHub connection
  3. Configure with your GitHub OAuth app credentials
  1. Go to GitHub Settings > Developer settings > OAuth Apps
  2. Click “New OAuth App”
  3. Set Homepage URL: https://yourdomain.com
  4. Set Authorization callback URL: https://YOUR_DOMAIN.auth0.com/login/callback
  5. Copy Client ID and Client Secret to Auth0

Get Auth0 credentials

Save these values for later:
  • Domain: your-tenant.auth0.com
  • Client ID: From your SPA application
  • Client Secret: From your SPA application (for backend)
  • Audience: https://api.dyeink.com

Set up Management API access

For user deletion functionality:
1

Create M2M application

  1. Go to APIs > Auth0 Management API
  2. Create a Machine-to-Machine application
  3. Grant permissions: delete:users
  4. Get the token for backend user deletion

Step 3: Cloudflare setup

Create R2 bucket

1

Create bucket

  1. Go to Cloudflare Dashboard > R2
  2. Create bucket: dyeink-images
2

Configure public access

  • Enable public access, or
  • Set up a custom domain for the bucket
3

Create API tokens

Create API tokens with R2 read/write permissions

Gather R2 credentials

You’ll need:
  • Account ID: From Cloudflare dashboard
  • Access Key ID: From R2 API tokens
  • Secret Access Key: From R2 API tokens
  • Bucket Name: dyeink-images
  • Public URL: https://your-bucket.r2.dev or custom domain

Step 4: Backend configuration

Install dependencies

cd backend
npm install
The backend uses these key dependencies:
{
  "fastify": "^4.26.0",
  "mongoose": "^8.1.1",
  "@fastify/jwt": "^8.0.0",
  "jwks-rsa": "^3.1.0",
  "@aws-sdk/client-s3": "^3.500.0",
  "hono": "^4.0.0"
}

Create environment file

Copy .env.example to .env and configure:
# MongoDB
MONGODB_URI=mongodb+srv://user:pass@cluster.mongodb.net/dyeink

# For Cloudflare Workers (MongoDB Data API)
MONGODB_DATA_API_URL=https://data.mongodb-api.com/app/YOUR_APP_ID/endpoint/data/v1
MONGODB_DATA_API_KEY=your-api-key
MONGODB_DATABASE=dyeink

# Auth0
AUTH0_DOMAIN=your-tenant.auth0.com
AUTH0_CLIENT_ID=your-client-id
AUTH0_CLIENT_SECRET=your-client-secret
AUTH0_AUDIENCE=https://api.dyeink.com
AUTH0_MANAGEMENT_API_TOKEN=your-management-token

# Cloudflare R2
R2_ACCOUNT_ID=your-account-id
R2_ACCESS_KEY_ID=your-access-key
R2_SECRET_ACCESS_KEY=your-secret-key
R2_BUCKET_NAME=dyeink-images
R2_PUBLIC_URL=https://your-r2-bucket.r2.dev

# Vercel (domain management)
VERCEL_TOKEN=your-vercel-token
VERCEL_PROJECT_ID=your-project-id
VERCEL_TEAM_ID=your-team-id

# App
PORT=3000
FRONTEND_URL=http://localhost:5173
Never commit .env files to version control. Add .env to your .gitignore.

Run development server

npm run dev
The backend will start on http://localhost:3000.

Step 5: Frontend configuration

Install dependencies

cd platform
npm install

Create environment file

Copy .env.example to .env:
VITE_AUTH0_DOMAIN=your-tenant.auth0.com
VITE_AUTH0_CLIENT_ID=your-client-id
VITE_AUTH0_AUDIENCE=https://api.dyeink.com
VITE_AUTH0_REDIRECT_URI=http://localhost:5173
VITE_API_BASE_URL=http://localhost:3000/api

Run development server

npm run dev
The frontend will start on http://localhost:5173.

Step 6: Data migration

Export data from Supabase

Export your existing data:
-- Export users (you'll need to recreate in Auth0)
SELECT * FROM auth.users;

-- Export posts
SELECT * FROM posts;

-- Export site_settings
SELECT * FROM site_settings;

-- Export subscribers
SELECT * FROM subscribers;

Transform and import to MongoDB

MongoDB document structure for posts:
{
  "_id": "user-id_1234567890",
  "userId": "auth0|user123",
  "title": "My Post",
  "slug": "my-post",
  "content": "<p>Content here</p>",
  "excerpt": "Excerpt here",
  "coverImage": "https://r2.dev/image.webp",
  "published": true,
  "publishedAt": "2024-01-01T00:00:00Z",
  "views": 100,
  "shares": 10,
  "createdAt": "2024-01-01T00:00:00Z",
  "updatedAt": "2024-01-01T00:00:00Z"
}
Use MongoDB Compass to import JSON data, or create a migration script using the Mongoose models.

Migrate images to R2

1

Download images from Supabase

Use Supabase Storage API to download all images
2

Upload to Cloudflare R2

Use the AWS S3 SDK (R2 is S3-compatible):
import { S3Client, PutObjectCommand } from '@aws-sdk/client-s3'

const s3 = new S3Client({
  region: 'auto',
  endpoint: `https://${R2_ACCOUNT_ID}.r2.cloudflarestorage.com`,
  credentials: {
    accessKeyId: R2_ACCESS_KEY_ID,
    secretAccessKey: R2_SECRET_ACCESS_KEY,
  },
})

await s3.send(new PutObjectCommand({
  Bucket: 'dyeink-images',
  Key: 'image.webp',
  Body: buffer,
  ContentType: 'image/webp',
}))
3

Update image URLs

Update all post coverImage fields to point to R2 URLs

Step 7: Deployment

1

Configure wrangler

Edit wrangler.toml with your settings
2

Add secrets

cd backend
wrangler secret put MONGODB_DATA_API_KEY
wrangler secret put MONGODB_DATA_API_URL
wrangler secret put AUTH0_DOMAIN
wrangler secret put AUTH0_AUDIENCE
wrangler secret put R2_ACCESS_KEY_ID
wrangler secret put R2_SECRET_ACCESS_KEY
# ... add all other secrets
3

Deploy

npm run deploy
Cloudflare Workers provide global edge deployment with sub-50ms response times worldwide.

Option 2: Traditional server

For platforms like Railway, Render, or DigitalOcean:
1

Build the backend

npm run build
2

Deploy

  1. Push your code to GitHub
  2. Connect your hosting platform to the repository
  3. Set environment variables in the platform dashboard
  4. Deploy

Deploy frontend to Vercel

1

Update environment variables

Set VITE_API_BASE_URL to your deployed backend URL
2

Deploy

vercel deploy --prod
Or connect your GitHub repository to Vercel for automatic deployments

Step 8: Testing

Test authentication

curl -X POST http://localhost:3000/api/auth/register \
  -H "Authorization: Bearer YOUR_AUTH0_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"auth0Id": "auth0|123", "email": "test@example.com"}'

Test post creation

curl -X POST http://localhost:3000/api/posts \
  -H "Authorization: Bearer YOUR_AUTH0_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"title": "Test Post", "slug": "test-post", "content": "Hello"}'

Test image upload

curl -X POST http://localhost:3000/api/upload \
  -H "Authorization: Bearer YOUR_AUTH0_TOKEN" \
  -F "file=@/path/to/image.jpg"

Troubleshooting

  • Ensure FRONTEND_URL is set correctly in backend .env
  • Check Auth0 allowed origins include your frontend URL
  • Verify Fastify CORS middleware is configured
  • Verify audience matches in both Auth0 and backend config
  • Check token hasn’t expired (default: 24 hours)
  • Ensure JWKS endpoint is accessible from your backend
  • Confirm Auth0 domain is correct (no https:// prefix in env vars)
  • Check IP whitelist in MongoDB Atlas (should include 0.0.0.0/0 for Workers)
  • Verify connection string format and credentials
  • For Workers: ensure Data API is enabled and API key is correct
  • Test connection using MongoDB Compass
  • Check bucket permissions and public access settings
  • Verify R2 credentials (Account ID, Access Key, Secret Key)
  • Ensure bucket name is correct
  • Check file size limits (R2 free tier: 10GB storage)
  • For Workers: Ensure all secrets are set via wrangler secret put
  • For traditional hosting: Check environment variables are set correctly
  • Verify build completes without errors
  • Check platform logs for runtime errors

File structure

Your project structure after migration:
/dyeink
├── /backend                 # Fastify backend
│   ├── /src
│   │   ├── /config         # Database config
│   │   ├── /middleware     # Auth middleware
│   │   ├── /models         # MongoDB schemas
│   │   ├── /routes         # API routes
│   │   ├── /services       # Business logic
│   │   ├── index.ts        # Fastify entry
│   │   └── worker.ts       # Cloudflare Worker entry
│   ├── package.json
│   ├── tsconfig.json
│   └── wrangler.toml       # Cloudflare config

├── /platform               # React frontend
│   ├── /src
│   │   ├── /lib
│   │   │   ├── auth0.ts    # Auth0 client
│   │   │   └── apiClient.ts # API client
│   │   ├── /services       # API services
│   │   ├── /stores         # Zustand stores
│   │   ├── /features       # Feature components
│   │   └── /components     # UI components
│   └── package.json

└── MIGRATION_GUIDE.md

Post-migration checklist

1

Verify all data migrated

  • All posts imported to MongoDB
  • Images uploaded to R2
  • Users recreated in Auth0
  • Settings migrated
2

Test core functionality

  • User authentication works
  • Post creation and editing
  • Image uploads
  • Custom domain routing
  • Public blog access
3

Update DNS

Point your domain to the new deployment
4

Monitor

  • Check error logs
  • Monitor performance metrics
  • Verify analytics tracking
5

Decommission old infrastructure

Once everything is stable, shut down Supabase resources
Keep your Supabase backup for at least 30 days after migration in case you need to reference or recover any data.

Support

If you encounter issues during migration:
  1. Check browser console for frontend errors
  2. Check backend logs for API errors
  3. Verify all environment variables are set correctly
  4. Test API endpoints individually using cURL or Postman
  5. Consult the MongoDB, Auth0, and Cloudflare documentation
Create a migration checklist and test each step in a development environment before migrating production data.