8.1 KiB
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:
- Creating R2 buckets
- Generating API credentials
- Uploading files to R2
- Configuring public access
- 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)
- Log in to Cloudflare Dashboard
- Navigate to R2 in the sidebar
- Click Create bucket
- 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)
- Bucket 1:
Option B: Wrangler CLI
# 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
- Go to My Profile (top right) → API Tokens
- Click Create Token
- Use Custom token template
- Set permissions:
- R2:Edit (for uploads)
- R2:Read (for downloads)
- Set account resources:
- Include: Specific account → Select your account
- Click Continue to summary → Create Token
- Copy the token immediately (you won't see it again)
- Go to R2 → Manage R2 API Tokens
- Click Create API Token
- Set permissions: Object Read & Write
- Set TTL: Never expire (or set expiration as needed)
- Click Create API Token
- Save both:
- Access Key ID
- Secret Access Key
Step 3: Configure Environment Variables
-
Copy
.env.exampleto.env.local:cd code cp .env.example .env.local -
Edit
.env.localand fill in:CLOUDFLARE_R2_ACCESS_KEY_ID=your_access_key_id_here CLOUDFLARE_R2_SECRET_ACCESS_KEY=your_secret_access_key_here -
Install dependencies:
npm install
Step 4: Upload Files to R2
Test Upload (Dry Run)
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
node scripts/upload-to-r2.js --type manuals
Upload Thumbnails Only
node scripts/upload-to-r2.js --type thumbnails
Upload Everything
node scripts/upload-to-r2.js --type all
Incremental Upload (Skip Existing Files)
node scripts/upload-to-r2.js --type all --incremental
Step 5: Configure Public Access
Enable Public Access
- Go to R2 → Select your bucket (e.g.,
vending-vm-manuals) - Click Settings tab
- Scroll to Public Access
- Click Allow Access → Allow List
- 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:
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:
- Go to R2 → Select bucket → Settings
- Scroll to CORS Policy
- Add CORS rule:
[ { "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
- Go to Cloudflare Dashboard → Pages
- Click Create a project
- Select Connect to Git
- Authorize Cloudflare to access GitHub (if not already connected)
- Select repository:
DMleadgen/rockymountainvending - Click Begin setup
Configure Build Settings
- Project name:
rocky-mountain-vending(or your choice) - Production branch:
main(ormaster) - Framework preset: Next.js (Static HTML Export)
- Build command:
cd code && npm install && npm run build - Build output directory:
code/out - Root directory:
/(leave empty, or set tocode/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
- Click Save and Deploy
- Cloudflare will build and deploy your site
- You'll get a Pages URL:
https://your-project.pages.dev
Custom Domain (Optional)
- Go to Pages → Your project → Custom domains
- Click Set up a custom domain
- Enter your domain:
rockymountainvending.com - Follow DNS instructions to add CNAME record
- SSL certificate is automatically provisioned
Step 8: Build and Test Locally
Build with R2 Upload
# From project root
./build-for-ghl.sh --upload-r2
This will:
- Upload manuals and thumbnails to R2
- Build the Next.js app
- Create deployment ZIP (for GHL if needed)
Build Without R2 Upload
./build-for-ghl.sh
Test Build Locally
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.localexists 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.jsonhas all dependencies - Ensure build output directory is correct (
code/out)
Manuals Not Loading
Issue: Manuals show 404
- Solution:
- Verify R2 buckets have files uploaded
- Check
NEXT_PUBLIC_MANUALS_BASE_URLis set correctly - Verify public access is enabled on buckets
- Check CORS settings if accessing from different domain
Migration Tools
For large-scale migrations, consider:
- Super Slurper: One-time comprehensive transfers
- 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
- ✅ Upload all manuals and thumbnails to R2
- ✅ Configure public URLs in environment variables
- ✅ Deploy to Cloudflare Pages
- ✅ Test manual downloads
- ✅ Monitor usage in Cloudflare Dashboard
Additional Resources
Support
For issues or questions:
- Check Cloudflare Dashboard for error messages
- Review build logs in Pages dashboard
- Check R2 bucket settings and permissions
- Verify environment variables are set correctly