Zero servers, zero egress fees, 10GB of free storage—the ultimate personal image hosting solution. Cloudflare's R2 offers 10GB free storage + zero egress fees. Combined with Pages static hosting, you can build a truly zero-cost image bed. This guide walks through deploying the open-source CloudFlare-ImgBed (2025 latest UI).

🎤 Introduction

In today's content creation era, a stable and efficient image hosting service is the must-have infrastructure for every blogger and developer. Cloudflare—the "cyber bodhisattva"—offers its R2 object storage with 10GB free storage + zero egress fees. Combined with Pages' static hosting capability, you can build a truly zero-cost image hosting solution. This guide walks you through the full deployment of the open-source CloudFlare-ImgBed project (2025 latest UI).

🔗 GitHub: https://github.com/MarSeventh/CloudFlare-ImgBed


🔍 Project Core Advantages

CloudFlare-ImgBed is a ready-to-use image hosting solution built on the following architecture:

ComponentTech StackFree Tier (Cloudflare)
FrontendVue.js (responsive design)-
Backend APICloudflare Workers (serverless)100K requests/day
StorageR2 Object Storage (S3-compatible)10GB + 1M writes/month
DatabaseCloudflare KV (metadata)10M reads/month
HostingCloudflare PagesUnlimited bandwidth + custom domain

Highlights:

  • Drag-and-drop web upload + API calls
  • Lossless image compression
  • One-click format conversion (Markdown / BBCode / HTML)
  • Password protection + guest upload controls
  • Multi-level directory management

⚙️ Pre-Deployment Requirements

Basic Accounts:

  • GitHub account (for forking the project)
  • Cloudflare account

Both only need an email to register.

Domain Requirements:

  • A custom domain (must be on Cloudflare DNS)
  • Optional subdomain like img.yourdomain.com

Payment Verification:

  • International credit card (Visa / MasterCard) or PayPal account
  • Used only to activate R2 (no charges within 10GB free tier)

🚀 Detailed Deployment Steps (2025 Latest UI)

Step 1: Create the R2 Bucket

  1. Cloudflare Dashboard → R2 Object StorageCreate bucket
  2. Configuration:

    • Name: imgbed (custom)
    • Location: Asia Pacific (lower latency)
    • Storage Class: Standard (free tier applies)
  3. Enable Public Access: Bucket Settings → Public Access URL → Click Enable

Step 2: Deploy the Pages Project

Fork the Project:

Create the Pages Service:

  1. Cloudflare Dashboard → Compute (Workers)Workers & PagesCreate applicationPages
  2. Connect GitHub → Select your forked repo
  3. Build Settings:
SettingValueNotes
Project Namecloudflare-imgbed (custom)Project identifier
Production BranchmainProduction branch
Build Commandnpm installv2.0 new command
Build Output/Keep default
  1. Click Deploy—takes 1–2 minutes to succeed

Bind a Custom Domain:

  • Pages project → Custom DomainsAdd domain (e.g., img.yourdomain.com)
  • ⚠️ Important: Users in China must bind a custom domain (the default *.pages.dev may be inaccessible)

Step 3: Key Configurations

Create the KV Database:

  1. Storage & DatabasesKV → Top-right Create Instance
  2. Name: img_url (must match exactly)
  3. Click Create

Bind to Pages:

  1. Pages project → SettingsBindingsAdd
  2. Variable name: img_url → Select the created KV
  3. Variable name: img_r2 → Select the R2 bucket
  4. Click Save

Redeploy:

  • Deploy → Click deployment details → Top-right Manage DeploymentRetry Deployment

Set Access Password (anti-abuse):

You can also configure these directly in the admin panel after deployment. Navigate to System SettingsSecurity Settings to set:

  • Backend admin username + password
  • Image hosting access password

Pages project → SettingsVariables and SecretsAdd:

  • AUTH_CODE: Custom upload password (letters + numbers)
  • BASIC_USER: Admin username
  • BASIC_PASS: Admin password

After deployment, visit the bound domain and configure in System Settings:

  • Upload Settings: Change to CloudFlareR2
  • Public Access URL: https://your-bound-domain
  • Page Settings: Default URL prefix = https://img.xxx.xxx/

🔐 Advanced Security & Optimization

Hotlink Protection:

  • Cloudflare Dashboard → SecurityWAFCustom Rules
  • Add Rule:

    • Field: Hostname → equals → img.yourdomain.com
    • AND Referrer → does not equal → www.yourblog.com
    • Action: Block

Rate-Limit Defense:

  • SecurityWAFRate Limit Rules
  • Rule: 100+ requests within 10 seconds → Block

Cache Optimization:

  • CachingPage RulesCreate Rule
  • URL: img.yourdomain.com/*
  • Edge Cache TTL: 1 month

China Access Acceleration:

  • DNS Settings → Enable China Network Optimization
  • Add an A record pointing to an optimal IP (e.g., 172.67.213.27)

🖼️ Three Ways to Use Your Image Hosting

1. Web Upload:

  • Visit your image hosting domain (e.g., img.yourdomain.com)
  • Enter your AUTH_CODE, then drag-and-drop to upload
  • Supports batch upload + directory management

2. API Integration:

curl --location --request POST 'https://img.yourdomain.com/upload' \
--header 'Authorization: Bearer YOUR_AUTH_CODE' \
--form 'file=@"image.jpg"'

3. Tool Integration:

  • PicGo: Install the S3 plugin, configure:

    • Endpoint: https://img.yourdomain.com
    • AccessKey / SecretKey: Get from the R2 API token
  • Alist: Mount R2 as a storage backend

💡 Troubleshooting

  • Deployment fails → Verify the build command is npm install
  • Images not accessible → Confirm the R2 bucket has public access enabled
  • Slow loading in China → Switch DNS resolution to an optimal IP
  • API upload returns 403 → Verify AUTH_CODE and R2 binding variable names

⚠️ Important Notes

Monthly operation limits (1M writes / 10M reads) are more than enough for personal use, but enabling security protection is strongly recommended to prevent malicious abuse!


🌈 Conclusion

The Cloudflare R2 + Pages combo delivers a truly zero-cost, zero-maintenance, permanent image hosting solution. Following this step-by-step tutorial, you can complete the deployment within 30 minutes. Whether it's blog illustration or project static asset hosting, this solution delivers enterprise-grade reliability.

Further Reading:

Note: This is the English translation of the original Chinese version. Visit the link to view the Chinese edition with full-length content.