Next.js website for Rocky Mountain Vending company featuring: - Product catalog with Stripe integration - Service areas and parts pages - Admin dashboard with Clerk authentication - SEO optimized pages with JSON-LD structured data Co-authored-by: Cursor <cursoragent@cursor.com>
314 lines
8.1 KiB
Markdown
314 lines
8.1 KiB
Markdown
# Cloudflare R2 Setup Guide
|
|
|
|
Complete guide for setting up Cloudflare R2 storage for vending machine manuals and thumbnails, and deploying to Cloudflare Pages.
|
|
|
|
## Overview
|
|
|
|
This guide covers:
|
|
1. Creating R2 buckets
|
|
2. Generating API credentials
|
|
3. Uploading files to R2
|
|
4. Configuring public access
|
|
5. Deploying to Cloudflare Pages via Git
|
|
|
|
## Prerequisites
|
|
|
|
- Cloudflare account (free tier available)
|
|
- Account ID: `bd6f76304a840ba11b75f9ced84264f4`
|
|
- S3 API Endpoint: `https://bd6f76304a840ba11b75f9ced84264f4.r2.cloudflarestorage.com`
|
|
- GitHub repository: `https://github.com/DMleadgen/rockymountainvending.git`
|
|
|
|
## Step 1: Create R2 Buckets
|
|
|
|
### Option A: Dashboard (Recommended)
|
|
|
|
1. Log in to [Cloudflare Dashboard](https://dash.cloudflare.com)
|
|
2. Navigate to **R2** in the sidebar
|
|
3. Click **Create bucket**
|
|
4. Create two buckets:
|
|
- **Bucket 1**: `vending-vm-manuals`
|
|
- Location: Automatic (or choose a region)
|
|
- Access: Public bucket (for direct access)
|
|
- **Bucket 2**: `vending-vm-thumbnails`
|
|
- Location: Automatic (or choose a region)
|
|
- Access: Public bucket (for direct access)
|
|
|
|
### Option B: Wrangler CLI
|
|
|
|
```bash
|
|
# Install wrangler (if not already installed)
|
|
npm install -g wrangler@latest
|
|
|
|
# Login to Cloudflare
|
|
wrangler login
|
|
|
|
# Create buckets
|
|
wrangler r2 bucket create vending-vm-manuals
|
|
wrangler r2 bucket create vending-vm-thumbnails
|
|
```
|
|
|
|
## Step 2: Generate API Credentials
|
|
|
|
1. Go to **My Profile** (top right) → **API Tokens**
|
|
2. Click **Create Token**
|
|
3. Use **Custom token** template
|
|
4. Set permissions:
|
|
- **R2:Edit** (for uploads)
|
|
- **R2:Read** (for downloads)
|
|
5. Set account resources:
|
|
- Include: Specific account → Select your account
|
|
6. Click **Continue to summary** → **Create Token**
|
|
7. **Copy the token immediately** (you won't see it again)
|
|
8. Go to **R2** → **Manage R2 API Tokens**
|
|
9. Click **Create API Token**
|
|
10. Set permissions: **Object Read & Write**
|
|
11. Set TTL: **Never expire** (or set expiration as needed)
|
|
12. Click **Create API Token**
|
|
13. **Save both**:
|
|
- Access Key ID
|
|
- Secret Access Key
|
|
|
|
## Step 3: Configure Environment Variables
|
|
|
|
1. Copy `.env.example` to `.env.local`:
|
|
```bash
|
|
cd code
|
|
cp .env.example .env.local
|
|
```
|
|
|
|
2. Edit `.env.local` and fill in:
|
|
```bash
|
|
CLOUDFLARE_R2_ACCESS_KEY_ID=your_access_key_id_here
|
|
CLOUDFLARE_R2_SECRET_ACCESS_KEY=your_secret_access_key_here
|
|
```
|
|
|
|
3. Install dependencies:
|
|
```bash
|
|
npm install
|
|
```
|
|
|
|
## Step 4: Upload Files to R2
|
|
|
|
### Test Upload (Dry Run)
|
|
|
|
```bash
|
|
cd code
|
|
node scripts/upload-to-r2.js --type all --dry-run
|
|
```
|
|
|
|
This will show what would be uploaded without actually uploading.
|
|
|
|
### Upload Manuals Only
|
|
|
|
```bash
|
|
node scripts/upload-to-r2.js --type manuals
|
|
```
|
|
|
|
### Upload Thumbnails Only
|
|
|
|
```bash
|
|
node scripts/upload-to-r2.js --type thumbnails
|
|
```
|
|
|
|
### Upload Everything
|
|
|
|
```bash
|
|
node scripts/upload-to-r2.js --type all
|
|
```
|
|
|
|
### Incremental Upload (Skip Existing Files)
|
|
|
|
```bash
|
|
node scripts/upload-to-r2.js --type all --incremental
|
|
```
|
|
|
|
## Step 5: Configure Public Access
|
|
|
|
### Enable Public Access
|
|
|
|
1. Go to **R2** → Select your bucket (e.g., `vending-vm-manuals`)
|
|
2. Click **Settings** tab
|
|
3. Scroll to **Public Access**
|
|
4. Click **Allow Access** → **Allow List**
|
|
5. Note the **Public R2.dev subdomain** (e.g., `https://pub-xxxxx.r2.dev`)
|
|
|
|
### Get Public URLs
|
|
|
|
After enabling public access, you'll get URLs like:
|
|
- Manuals: `https://pub-xxxxx.r2.dev` (or custom domain)
|
|
- Thumbnails: `https://pub-yyyyy.r2.dev` (or custom domain)
|
|
|
|
### Update Environment Variables
|
|
|
|
Update `.env.local` with the public URLs:
|
|
|
|
```bash
|
|
NEXT_PUBLIC_MANUALS_BASE_URL=https://pub-xxxxx.r2.dev
|
|
NEXT_PUBLIC_THUMBNAILS_BASE_URL=https://pub-yyyyy.r2.dev
|
|
```
|
|
|
|
## Step 6: Configure CORS (If Needed)
|
|
|
|
If you need to access R2 from a different domain:
|
|
|
|
1. Go to **R2** → Select bucket → **Settings**
|
|
2. Scroll to **CORS Policy**
|
|
3. Add CORS rule:
|
|
```json
|
|
[
|
|
{
|
|
"AllowedOrigins": ["https://rockymountainvending.com", "https://www.rockymountainvending.com"],
|
|
"AllowedMethods": ["GET", "HEAD"],
|
|
"AllowedHeaders": ["*"],
|
|
"ExposeHeaders": ["ETag"],
|
|
"MaxAgeSeconds": 3600
|
|
}
|
|
]
|
|
```
|
|
|
|
## Step 7: Deploy to Cloudflare Pages
|
|
|
|
### Connect GitHub Repository
|
|
|
|
1. Go to **Cloudflare Dashboard** → **Pages**
|
|
2. Click **Create a project**
|
|
3. Select **Connect to Git**
|
|
4. Authorize Cloudflare to access GitHub (if not already connected)
|
|
5. Select repository: `DMleadgen/rockymountainvending`
|
|
6. Click **Begin setup**
|
|
|
|
### Configure Build Settings
|
|
|
|
1. **Project name**: `rocky-mountain-vending` (or your choice)
|
|
2. **Production branch**: `main` (or `master`)
|
|
3. **Framework preset**: **Next.js (Static HTML Export)**
|
|
4. **Build command**: `cd code && npm install && npm run build`
|
|
5. **Build output directory**: `code/out`
|
|
6. **Root directory**: `/` (leave empty, or set to `code/` if needed)
|
|
|
|
### Set Environment Variables
|
|
|
|
In Pages project settings → **Environment Variables**, add:
|
|
|
|
```
|
|
NEXT_PUBLIC_MANUALS_BASE_URL=https://pub-xxxxx.r2.dev
|
|
NEXT_PUBLIC_THUMBNAILS_BASE_URL=https://pub-yyyyy.r2.dev
|
|
NEXT_PUBLIC_SITE_URL=https://rockymountainvending.com
|
|
NEXT_PUBLIC_SITE_DOMAIN=rockymountainvending.com
|
|
```
|
|
|
|
### Deploy
|
|
|
|
1. Click **Save and Deploy**
|
|
2. Cloudflare will build and deploy your site
|
|
3. You'll get a Pages URL: `https://your-project.pages.dev`
|
|
|
|
### Custom Domain (Optional)
|
|
|
|
1. Go to **Pages** → Your project → **Custom domains**
|
|
2. Click **Set up a custom domain**
|
|
3. Enter your domain: `rockymountainvending.com`
|
|
4. Follow DNS instructions to add CNAME record
|
|
5. SSL certificate is automatically provisioned
|
|
|
|
## Step 8: Build and Test Locally
|
|
|
|
### Build with R2 Upload
|
|
|
|
```bash
|
|
# From project root
|
|
./build-for-ghl.sh --upload-r2
|
|
```
|
|
|
|
This will:
|
|
1. Upload manuals and thumbnails to R2
|
|
2. Build the Next.js app
|
|
3. Create deployment ZIP (for GHL if needed)
|
|
|
|
### Build Without R2 Upload
|
|
|
|
```bash
|
|
./build-for-ghl.sh
|
|
```
|
|
|
|
### Test Build Locally
|
|
|
|
```bash
|
|
cd code
|
|
npm run build
|
|
npm run start
|
|
```
|
|
|
|
Visit `http://localhost:3000` and verify manuals load from R2 URLs.
|
|
|
|
## Troubleshooting
|
|
|
|
### Upload Script Fails
|
|
|
|
**Error**: "CLOUDFLARE_R2_ACCESS_KEY_ID must be set"
|
|
- **Solution**: Make sure `.env.local` exists and has correct credentials
|
|
|
|
**Error**: "Bucket not found"
|
|
- **Solution**: Create buckets in Cloudflare Dashboard first
|
|
|
|
### Files Not Accessible
|
|
|
|
**Issue**: 403 Forbidden when accessing R2 URLs
|
|
- **Solution**: Enable public access in bucket settings
|
|
|
|
**Issue**: CORS errors
|
|
- **Solution**: Configure CORS policy in bucket settings
|
|
|
|
### Build Fails in Pages
|
|
|
|
**Error**: Build command fails
|
|
- **Solution**: Check build logs in Pages dashboard
|
|
- Verify `package.json` has all dependencies
|
|
- Ensure build output directory is correct (`code/out`)
|
|
|
|
### Manuals Not Loading
|
|
|
|
**Issue**: Manuals show 404
|
|
- **Solution**:
|
|
1. Verify R2 buckets have files uploaded
|
|
2. Check `NEXT_PUBLIC_MANUALS_BASE_URL` is set correctly
|
|
3. Verify public access is enabled on buckets
|
|
4. Check CORS settings if accessing from different domain
|
|
|
|
## Migration Tools
|
|
|
|
For large-scale migrations, consider:
|
|
|
|
- **[Super Slurper](https://developers.cloudflare.com/r2/data-migration/super-slurper/)**: One-time comprehensive transfers
|
|
- **[Sippy](https://developers.cloudflare.com/r2/data-migration/sippy/)**: Incremental migration, populating as objects are requested
|
|
|
|
## Free Tier Limits
|
|
|
|
- **Storage**: 10 GB free
|
|
- **Class A Operations** (writes): 1 million/month free
|
|
- **Class B Operations** (reads): 10 million/month free
|
|
- **Egress**: Free up to 10 TB/month via CDN
|
|
|
|
## Next Steps
|
|
|
|
1. ✅ Upload all manuals and thumbnails to R2
|
|
2. ✅ Configure public URLs in environment variables
|
|
3. ✅ Deploy to Cloudflare Pages
|
|
4. ✅ Test manual downloads
|
|
5. ✅ Monitor usage in Cloudflare Dashboard
|
|
|
|
## Additional Resources
|
|
|
|
- [Cloudflare R2 Documentation](https://developers.cloudflare.com/r2/)
|
|
- [Cloudflare Pages Documentation](https://developers.cloudflare.com/pages/)
|
|
- [Wrangler CLI Documentation](https://developers.cloudflare.com/workers/wrangler/)
|
|
|
|
## Support
|
|
|
|
For issues or questions:
|
|
1. Check Cloudflare Dashboard for error messages
|
|
2. Review build logs in Pages dashboard
|
|
3. Check R2 bucket settings and permissions
|
|
4. Verify environment variables are set correctly
|
|
|
|
|