К основному содержимому

Cloudflare R2: хранилище без платы за исходящий трафик

Cloudflare · 19.04.2026 · 4 мин чтения
Иллюстрация к статье «Cloudflare R2: объектное хранилище без платы за исходящий трафик»

Cloudflare R2 — объектное хранилище, совместимое с S3 API. Главное отличие от Amazon S3: нет платы за egress (исходящий трафик). Отлично подходит для хранения изображений, видео, бэкапов.

Тарифы R2

РесурсFreePaid
Хранилище10 ГБ/мес$0.015/ГБ
Class A операции (PUT)1 млн/мес$4.50/млн
Class B операции (GET)10 млн/мес$0.36/млн
Egress трафикБесплатно ✅Бесплатно ✅

Создание бакета R2

R2 → Create bucket → введите имя → Create bucket.

Для публичного доступа (CDN): Settings → Public Access → Allow Access.

# URL публичного файла:
https://pub-HASH.r2.dev/folder/filename.jpg

# Или кастомный домен:
https://media.example.com/folder/filename.jpg

Загрузка файлов через S3 API

# Настроить aws-cli для R2
aws configure --profile cloudflare
# AWS Access Key ID: R2 Access Key
# AWS Secret Access Key: R2 Secret Key
# Default region: auto

# Загрузить файл
aws s3 cp file.jpg s3://my-bucket/file.jpg     --endpoint-url https://ACCOUNT_ID.r2.cloudflarestorage.com     --profile cloudflare

# Синхронизировать папку
aws s3 sync ./media/ s3://my-bucket/     --endpoint-url https://ACCOUNT_ID.r2.cloudflarestorage.com     --profile cloudflare

WordPress + R2 через плагин

Используйте плагин «Media Cloud» или «Offload Media» с настройками R2:

  • Storage Provider: S3 Compatible
  • Endpoint: https://ACCOUNT_ID.r2.cloudflarestorage.com
  • Region: auto
✅ R2 идеально для разгрузки сервера: храните изображения WordPress в R2 и раздавайте через Cloudflare CDN — нет платы за трафик и высокая скорость.

R2 в сравнении с S3 и локальным диском

КритерийR2Amazon S3Локальный диск сервера
Плата за egressНетЕсть, по объёмуНет (входит в тариф сервера)
S3-совместимый APIДаДа (эталон)Нет
Встроенный CDNЧерез CloudflareНужен отдельно CloudFrontНет
Ограничение по местуПрактически нетПрактически нетРазмер диска VPS

Разбор типичных ошибок

Access Denied при загрузке через S3 API

Чаще всего означает, что R2 Access Key и Secret Key не совпадают с бакетом (ключи привязаны к конкретному аккаунту Cloudflare, а не глобальны), либо endpoint URL указан с ошибкой — в нём обязателен именно Account ID, а не имя бакета или домена.

CORS-ошибка при обращении к бакету из браузера

Если файлы из R2 загружаются напрямую JS-кодом на клиенте (не просто как <img src>), нужно настроить CORS-политику бакета: Settings → CORS Policy → указать разрешённые Origin, методы и заголовки. Без этого браузер блокирует ответ на уровне Same-Origin Policy, даже если сам файл отдаётся с кодом 200.

Проверка результата

# Проверить что публичный доступ к файлу работает
curl -I https://pub-HASH.r2.dev/folder/filename.jpg

# Ожидаемо: HTTP/2 200, content-type: image/jpeg

# Проверить список объектов через aws-cli
aws s3 ls s3://my-bucket/ --endpoint-url https://ACCOUNT_ID.r2.cloudflarestorage.com --profile cloudflare

Когда R2 не подходит

  • Нужна активная выборка и сложные запросы по метаданным файлов — R2, как и S3, это объектное хранилище, а не база данных, для поиска нужен отдельный индекс.
  • Нужна файловая система с блокировками и одновременной записью с нескольких серверов в один файл — объектные хранилища не для этого, нужен NFS или общий диск.
  • Хранятся изображения или видео и нужна обработка на лету (ресайз, транскодинг) — для этого больше подходит Cloudflare Images/Stream, чем сырой R2-бакет.

R2 поддерживает Object Lifecycle Rules — можно настроить автоматическое удаление объектов старше определённого срока (например, временные бэкапы) или перевод в более дешёвый класс хранения. Правила настраиваются в Settings бакета → Object lifecycle rules.

Для временного доступа к приватным файлам без включения полного публичного доступа используйте presigned URL — подписанную ссылку с ограниченным сроком действия, которую генерирует SDK или aws-cli через тот же S3-совместимый API. Такая ссылка отдаёт файл напрямую, без прохождения через ваш сервер.

Перенести существующий бакет с Amazon S3 на R2 можно утилитой rclone или обычным aws s3 sync, указав оба endpoint — исходный и ACCOUNT_ID.r2.cloudflarestorage.com. Для больших объёмов данных перенос стоит делать частями, чтобы не упереться в лимиты запросов за раз.

Расход по операциям Class A и Class B, а также объём хранилища видно в Dashboard → R2 → Metrics по каждому бакету отдельно — удобно, если несколько проектов используют общий аккаунт Cloudflare и нужно понимать, что именно генерирует нагрузку.

При создании бакета можно выбрать jurisdiction (например, EU) — это гарантирует, что данные физически не покидают выбранный регион, что важно для проектов с требованиями по локализации данных вроде GDPR.

Статья помогла?
← Назад в базу знаний Задать вопрос поддержке