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
Deploy a cluster
Deploy a free cluster (M0) or use your $50 credit for a paid tier
Create database user
Create a database user with read/write access to the dyeink database
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:
Navigate to Data API
Go to Data Services > Data API
Enable and configure
Enable the Data API
Copy the App ID
Generate an API Key
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
Create SPA application
Go to Auth0 Dashboard
Create a new Single Page Application
Name it “Dyeink”
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
Create the API
Go to APIs > Create API
Name: DyeInk API
Identifier: https://api.dyeink.com (this is your audience)
Signing Algorithm: RS256
Configure social connections
Enable GitHub login
Go to Authentication > Social
Enable GitHub connection
Configure with your GitHub OAuth app credentials
How to create GitHub OAuth app
Go to GitHub Settings > Developer settings > OAuth Apps
Click “New OAuth App”
Set Homepage URL: https://yourdomain.com
Set Authorization callback URL: https://YOUR_DOMAIN.auth0.com/login/callback
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:
Create M2M application
Go to APIs > Auth0 Management API
Create a Machine-to-Machine application
Grant permissions: delete:users
Get the token for backend user deletion
Step 3: Cloudflare setup
Create R2 bucket
Create bucket
Go to Cloudflare Dashboard > R2
Create bucket: dyeink-images
Configure public access
Enable public access, or
Set up a custom domain for the bucket
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
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
The backend will start on http://localhost:3000.
Step 5: Frontend configuration
Install dependencies
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
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
Download images from Supabase
Use Supabase Storage API to download all images
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' ,
}))
Update image URLs
Update all post coverImage fields to point to R2 URLs
Step 7: Deployment
Option 1: Cloudflare Workers (recommended)
Configure wrangler
Edit wrangler.toml with your settings
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
Cloudflare Workers provide global edge deployment with sub-50ms response times worldwide.
Option 2: Traditional server
For platforms like Railway, Render, or DigitalOcean:
Deploy
Push your code to GitHub
Connect your hosting platform to the repository
Set environment variables in the platform dashboard
Deploy
Deploy frontend to Vercel
Update environment variables
Set VITE_API_BASE_URL to your deployed backend URL
Deploy
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)
MongoDB connection issues
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
Update DNS
Point your domain to the new deployment
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:
Check browser console for frontend errors
Check backend logs for API errors
Verify all environment variables are set correctly
Test API endpoints individually using cURL or Postman
Consult the MongoDB, Auth0, and Cloudflare documentation
Create a migration checklist and test each step in a development environment before migrating production data.