Deploy to Cloudflare Pages
Deploy to Cloudflare Pages
Section titled “Deploy to Cloudflare Pages”Deploy your podcast website to Cloudflare Pages for fast, global edge hosting with automatic deployments, unlimited bandwidth, and generous free tier.
Why Cloudflare Pages?
Section titled “Why Cloudflare Pages?”- ✅ Free tier: Unlimited bandwidth, 500 builds/month
- ✅ Global CDN: 275+ cities worldwide
- ✅ Fast builds: Typically 1-2 minutes
- ✅ Automatic deployments: Push to git → auto-deploy
- ✅ Preview deployments: Every PR gets a preview URL
- ✅ Zero config: Works out of the box with Astro
- ✅ API routes: Full serverless function support
Prerequisites
Section titled “Prerequisites”- Cloudflare account (sign up free)
- Podcast website in GitHub repository
- Environment variables documented in
.env.template
Deployment Methods
Section titled “Deployment Methods”Method 1: Cloudflare Dashboard (Recommended)
Section titled “Method 1: Cloudflare Dashboard (Recommended)”Step 1: Push to GitHub
# Initialize git (if not done)git initgit add .git commit -m "Initial commit"
# Create GitHub repogh repo create my-podcast --public
# Push codegit remote add origin https://github.com/username/my-podcast.gitgit push -u origin mainStep 2: Connect to Cloudflare
- Go to Cloudflare Dashboard
- Click “Workers & Pages”
- Click “Create application”
- Click “Pages” tab
- Click “Connect to Git”
- Select GitHub (authorize if first time)
- Select your repository
- Click “Begin setup”
Step 3: Configure Build
Project name: my-podcastProduction branch: mainFramework preset: AstroBuild command: npm run buildBuild output directory: distRoot directory: /Step 4: Environment Variables
Click “Add environment variables” and add:
PUBLIC_SANITY_PROJECT_ID = abc123xyzPUBLIC_SANITY_DATASET = productionPUBLIC_SANITY_API_VERSION = 2024-01-01PUBLIC_SITE_URL = https://my-podcast.pages.dev
# Optional (if using features)SANITY_API_TOKEN = sk_...RESEND_API_KEY = re_...NOTIFICATION_EMAIL = [email protected]CONVERTKIT_API_KEY = ...CONVERTKIT_FORM_ID = ...PUBLIC_GA_MEASUREMENT_ID = G-...SENTRY_DSN = https://...Step 5: Deploy
Click “Save and Deploy”
Watch the build:
Initializing build environmentCloning repositoryInstalling dependenciesRunning build commandDeploying to Cloudflare network✅ Success! Deployed to https://my-podcast.pages.devStep 6: Visit Site
Your site is live at: https://my-podcast.pages.dev
Method 2: Wrangler CLI
Section titled “Method 2: Wrangler CLI”Deploy directly from command line:
Step 1: Install Wrangler
npm install -g wranglerStep 2: Login
wrangler loginStep 3: Build
npm run buildStep 4: Deploy
wrangler pages deploy dist --project-name=my-podcastOutput:
✨ Success! Deployed to https://my-podcast.pages.devMethod 3: GitHub Actions (Automated)
Section titled “Method 3: GitHub Actions (Automated)”Already configured in the template:
.github/workflows/deploy.yml:
name: Deploy to Cloudflare Pages
on: push: branches: [main] pull_request:
jobs: deploy: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - uses: actions/setup-node@v4 with: node-version: '18' - run: npm ci - run: npm run build - uses: cloudflare/pages-action@v1 with: apiToken: ${{ secrets.CLOUDFLARE_API_TOKEN }} accountId: ${{ secrets.CLOUDFLARE_ACCOUNT_ID }} projectName: my-podcast directory: distSetup:
-
Get Cloudflare API Token:
- Dashboard → My Profile → API Tokens
- Create token with “Cloudflare Pages” template
-
Get Account ID:
- Dashboard → Workers & Pages → Account ID
-
Add GitHub Secrets:
- Repository → Settings → Secrets and variables → Actions
- Add:
CLOUDFLARE_API_TOKEN - Add:
CLOUDFLARE_ACCOUNT_ID
-
Push to main:
git pushGitHub Actions automatically deploys!
Custom Domains
Section titled “Custom Domains”Step 1: Add Custom Domain
Section titled “Step 1: Add Custom Domain”- In Cloudflare Pages project
- Click “Custom domains”
- Click “Set up a custom domain”
- Enter domain:
yourpodcast.com - Click “Continue”
Step 2: Configure DNS
Section titled “Step 2: Configure DNS”If domain is on Cloudflare:
- DNS configured automatically ✅
If domain is elsewhere:
- Add CNAME record:
Type: CNAMEName: @ (or subdomain)Value: my-podcast.pages.devTTL: Auto
Step 3: Wait for SSL
Section titled “Step 3: Wait for SSL”SSL certificate provisions automatically (5-10 minutes).
Check status:
✅ Active - Certificate provisioned⏳ Pending - Certificate provisioning❌ Failed - Check DNS configurationStep 4: Update Environment Variables
Section titled “Step 4: Update Environment Variables”Update PUBLIC_SITE_URL:
Before: https://my-podcast.pages.devAfter: https://yourpodcast.comStep 5: Rebuild
Section titled “Step 5: Rebuild”Trigger rebuild to use new URL:
git commit --allow-empty -m "Update site URL"git pushBuild Configuration
Section titled “Build Configuration”Build Settings
Section titled “Build Settings”Default Cloudflare Pages settings for Astro:
Framework preset: AstroBuild command: npm run buildBuild output directory: distNode version: 18 (or higher)Root directory: /Custom Build Command
Section titled “Custom Build Command”Modify if needed:
# Type check before buildBuild command: npm run build
# Skip type checking (faster builds)Build command: astro build
# Custom environmentBuild command: NODE_OPTIONS="--max-old-space-size=4096" npm run buildBuild Caching
Section titled “Build Caching”Cloudflare caches:
- ✅
node_modules/(dependencies) - ✅
.astro/(Astro cache) - ✅ Build assets
Benefits:
First build: 2-3 minutesSubsequent builds: 30-60 seconds (80% faster)Environment Variables
Section titled “Environment Variables”Adding Variables
Section titled “Adding Variables”- Pages project → Settings → Environment variables
- Click “Add variable”
- Enter name and value
- Select environment: Production, Preview, or both
- Click “Save”
Variable Types
Section titled “Variable Types”Public Variables (accessible in browser):
PUBLIC_SANITY_PROJECT_IDPUBLIC_SANITY_DATASETPUBLIC_SITE_URLPUBLIC_GA_MEASUREMENT_IDPrivate Variables (server-only):
SANITY_API_TOKENRESEND_API_KEYCONVERTKIT_API_KEYSENTRY_DSNRequired Variables
Section titled “Required Variables”Minimum variables for basic site:
PUBLIC_SANITY_PROJECT_ID = abc123xyzPUBLIC_SANITY_DATASET = productionPUBLIC_SITE_URL = https://yourpodcast.comSee: Environment Variables for complete list.
Automatic Deployments
Section titled “Automatic Deployments”On Push to Main
Section titled “On Push to Main”git add .git commit -m "Add new episode"git push
# Triggers automatic deployment# ↓# Build runs on Cloudflare# ↓# Site updates in ~1-2 minutesPreview Deployments
Section titled “Preview Deployments”Every pull request gets a preview URL:
git checkout -b new-featuregit push -u origin new-feature
# Create PR on GitHub# ↓# Preview deployment created# ↓# https://abc123.my-podcast.pages.devBenefits:
- Test changes before merging
- Share with team for review
- No impact on production
Monitoring
Section titled “Monitoring”Build Logs
Section titled “Build Logs”View build logs in Cloudflare Dashboard:
- Pages project → Deployments
- Click deployment
- View logs:
Installing dependencies...Running build command...✅ Build succeeded in 45s
Analytics
Section titled “Analytics”Built-in analytics:
- Pages project → Analytics
- View:
- Page views
- Unique visitors
- Top pages
- Geographic distribution
Function Logs
Section titled “Function Logs”View serverless function logs:
- Pages project → Functions
- Click “Real-time logs”
- See API route execution
Performance
Section titled “Performance”Edge Network
Section titled “Edge Network”Cloudflare serves from 275+ locations:
User in Tokyo → Served from Tokyo edgeUser in London → Served from London edgeUser in NYC → Served from NYC edgeResult: Sub-100ms load times globally.
Caching
Section titled “Caching”Cloudflare caches static assets:
First visit: 200ms (origin fetch)Repeat visits: 20ms (edge cache)Cache invalidation:
- Automatic on new deployment
- Manual: Settings → Caching → Purge Cache
Optimization
Section titled “Optimization”Cloudflare automatically:
- ✅ Minifies HTML, CSS, JS
- ✅ Compresses with Brotli
- ✅ Optimizes images
- ✅ HTTP/3 support
Troubleshooting
Section titled “Troubleshooting”Build failed
Section titled “Build failed”Check build logs:
- Deployments → Failed deployment → View logs
- Look for errors:
Error: Missing environment variable PUBLIC_SANITY_PROJECT_IDError: Command failed with exit code 1
Common fixes:
- Add missing environment variables
- Check
package.jsonscripts - Verify Node version compatibility
Site shows 404
Section titled “Site shows 404”Check output directory:
- Must be
dist(notbuildorpublic)
Check build command:
- Must be
npm run build(orastro build)
API routes not working
Section titled “API routes not working”Check 1: API routes in correct location
src/pages/api/contribute.ts ✅src/api/contribute.ts ❌Check 2: Export format
// ✅ Correctexport const POST: APIRoute = async (context) => { ... };
// ❌ Wrongexport default function handler(req, res) { ... }Environment variables not accessible
Section titled “Environment variables not accessible”Check 1: Variables are added in Cloudflare dashboard
Check 2: Variable names match code
// Code expects:getEnv('PUBLIC_SANITY_PROJECT_ID', context)
// Dashboard must have:PUBLIC_SANITY_PROJECT_ID = abc123Check 3: Using hosting adapter
// ✅ Cloudflare-compatibleimport { getEnv } from '@rejected-media/podcast-framework-core';const id = getEnv('PUBLIC_SANITY_PROJECT_ID', context);
// ❌ Won't work on Cloudflareconst id = process.env.PUBLIC_SANITY_PROJECT_ID;Related
Section titled “Related”- Environment Variables - Complete variable list
- Custom Domains - Set up custom domain
- Netlify - Alternative platform
Next Steps
Section titled “Next Steps”- Environment Variables - Configure production variables
- Custom Domains - Add custom domain
- Monitoring - Monitor your site (coming soon)