Skip to content

Cloudflare R2 Setup Guide โ€‹

Panduan lengkap untuk setup Cloudflare R2 (object storage) untuk file dan image uploads.

๐Ÿ“‹ Overview โ€‹

Cloudflare R2 adalah object storage yang kompatibel dengan S3 API, dengan keuntungan:

  • No egress fees - Tidak ada biaya keluar (bandwidth)
  • S3 Compatible - Bisa pakai AWS SDK
  • Global CDN - Otomatis terdistribusi global
  • Murah - $0.015 per GB per bulan

๐Ÿš€ Langkah Setup โ€‹

1. Buka Cloudflare Dashboard โ€‹

  1. Login ke Cloudflare Dashboard
  2. Pilih account Anda
  3. Di sidebar, klik "R2"

2. Create Bucket โ€‹

  1. Klik tombol "Create bucket"
  2. Masukkan Bucket name:
    • Gunakan nama unik (contoh: myapp-uploads-2024)
    • Hanya lowercase, numbers, dan hyphens
    • Min 3, max 63 characters
  3. Pilih Location (opsional, default adalah Automatic):
    • Automatic - Data direplikasi otomatis (recommended)
    • Atau pilih region spesifik (EU, US, Asia)
  4. Klik "Create bucket"

3. Enable Public Access (Optional) โ€‹

Jika file perlu diakses publik (seperti avatar):

  1. Klik bucket yang sudah dibuat
  2. Tab "Settings"
  3. Di bagian "Public Access", klik "Allow"
  4. Catat Public URL (contoh: https://pub-abc123.r2.dev)

Note: Jika tidak di-public, file hanya bisa diakses via presigned URL.

4. Create API Token (for R2) โ€‹

Cloudflare R2 menggunakan 2 jenis credential:

  1. Di sidebar R2, klik "Manage R2 API Tokens"
  2. Klik "Create API Token"
  3. Pilih permissions:
    • Object Read & Write โœ… (untuk upload dan delete)
  4. Pilih bucket:
    • Specific buckets โ†’ pilih bucket Anda
    • Atau All buckets
  5. Set TTL (expiration):
    • Custom โ†’ pilih durasi (atau leave default)
  6. Klik "Create API Token"

Simpan informasi ini:

Access Key ID:     abc123def456...
Secret Access Key: xyz789ghi012...

Penting: Secret Access Key hanya ditampilkan sekali! Simpan dengan aman.

Option B: Global API Key (Alternative) โ€‹

Jika butuh access untuk semua buckets:

  1. Di sidebar utama Cloudflare, klik "My Profile"
  2. Tab "API Tokens"
  3. Klik "Create Token"
  4. Template: "R2 Worker"
  5. Atau custom token dengan permission:
    • Account > Cloudflare R2 > Edit
  6. Klik "Continue" โ†’ "Create Token"

5. Get Account ID โ€‹

Account ID dibutuhkan untuk R2 API:

  1. Di sidebar utama (bukan R2), lihat panel kanan
  2. Atau klik "Workers & Pages"
  3. Account ID terlihat di panel kanan
Account ID: 1a2b3c4d5e6f7g8h9i0j

๐Ÿ”ง Konfigurasi di Project โ€‹

1. Update Environment Variables โ€‹

Edit file .env:

env
# Cloudflare R2 Configuration
R2_ACCOUNT_ID=your_account_id_here
R2_ACCESS_KEY_ID=your_access_key_id
R2_SECRET_ACCESS_KEY=your_secret_access_key
R2_BUCKET_NAME=your-bucket-name
R2_PUBLIC_URL=https://pub-yourid.r2.dev

2. Dapatkan Public URL โ€‹

Jika bucket di-public:

https://pub-abc123def456.r2.dev

Jika private, public URL tidak ada, gunakan presigned URL saja.

๐Ÿงช Testing R2 โ€‹

Test Upload via Script โ€‹

bash
# Install AWS CLI (opsional, untuk testing)
pip install awscli

# Configure
aws configure --profile r2
# AWS Access Key ID: your_r2_access_key
# AWS Secret Access Key: your_r2_secret_key
# Default region: auto
# Default output: json

# Test upload
aws s3 cp test.txt s3://your-bucket/ \
  --endpoint-url https://your-account-id.r2.cloudflarestorage.com \
  --profile r2

Test via Aplikasi โ€‹

  1. Jalankan aplikasi:
bash
npm run dev
  1. Login ke aplikasi
  2. Buka Profile page
  3. Upload avatar
  4. Check browser console untuk URL gambar

๐Ÿ“ Struktur Folder di R2 โ€‹

Recommended structure:

your-bucket/
โ”œโ”€โ”€ avatars/
โ”‚   โ””โ”€โ”€ {user-id}/
โ”‚       โ””โ”€โ”€ avatar.webp
โ”œโ”€โ”€ uploads/
โ”‚   โ””โ”€โ”€ {user-id}/
โ”‚       โ”œโ”€โ”€ document.pdf
โ”‚       โ””โ”€โ”€ image.png
โ””โ”€โ”€ images/
    โ””โ”€โ”€ {user-id}/
        โ””โ”€โ”€ photo.webp

Sudah diimplementasikan di:

  • src/lib/storage/r2.ts - function generateFileKey()
  • src/routes/api/upload/image/+server.ts

๐Ÿ”’ Security Best Practices โ€‹

1. Restrict CORS (Opsional) โ€‹

Di bucket settings:

  1. Tab "CORS Policy"
  2. Add policy:
json
[
  {
    "AllowedOrigins": ["https://yourdomain.com"],
    "AllowedMethods": ["GET", "PUT"],
    "AllowedHeaders": ["*"],
    "MaxAgeSeconds": 3000
  }
]

2. Lifecycle Rules (Opsional) โ€‹

Auto-delete old files:

  1. Tab "Lifecycle Rules"
  2. Klik "Add rule"
  3. Configure:
    • Delete objects after 30 days (contoh untuk temporary files)

3. Access Control โ€‹

  • Jangan share Access Key dan Secret
  • Gunakan Least Privilege - hanya permission yang dibutuhkan
  • Rotate keys secara berkala

๐Ÿ’ฐ Pricing โ€‹

UsagePrice
Storage$0.015 per GB per month
Class A Operations (upload)$4.50 per million requests
Class B Operations (download)$0.36 per million requests
Egress (bandwidth out)FREE ๐ŸŽ‰

Free tier:

  • 10 GB storage/month
  • 1 million Class A operations
  • 10 million Class B operations

โš ๏ธ Troubleshooting โ€‹

"The Access Key ID you provided does not exist" โ€‹

Penyebab:

  • Access Key salah
  • Key sudah di-delete
  • Key expired (jika set TTL)

Solusi:

  1. Buat API Token baru di R2 dashboard
  2. Copy Access Key ID dan Secret dengan benar

"NoSuchBucket" โ€‹

Penyebab: Bucket name salah

Solusi:

env
# Salah
R2_BUCKET_NAME=https://pub-xxx.r2.dev

# Benar
R2_BUCKET_NAME=my-bucket-name

"Upload failed: 403 Forbidden" โ€‹

Penyebab: Token tidak punya permission write

Solusi:

  1. Check API Token permissions
  2. Pastikan "Object Read & Write" โœ…
  3. Pastikan bucket sudah di-select

"The request signature we calculated does not match" โ€‹

Penyebab: Secret Access Key salah

Solusi:

  1. Buat token baru
  2. Copy Secret Access Key dengan hati-hati (no spaces)

Image tidak muncul setelah upload โ€‹

Penyebab:

  1. Bucket tidak public
  2. URL salah

Solusi:

  1. Check bucket Settings โ†’ Public Access
  2. Jika private, gunakan presigned URL
  3. Check R2_PUBLIC_URL di .env

๐Ÿ”— Resources โ€‹


Setelah setup selesai, aplikasi bisa upload file dan images ke R2! ๐ŸŽ‰

SvelteKit Cloudflare Starter - Build Fast, Deploy Everywhere ๐Ÿš€