# 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