本文详解如何将WordPress媒体库迁移到Cloudflare R2,实现低成本、高速度的全球CDN分发。
为什么用Cloudflare R2(而非AWS S3)
| 方案 | 存储成本 | 流量成本 | 速度 |
|------|----------|
| 服务器本地 | 低(含服务器) | 高(服务器带宽) | 中 |
| Cloudflare R2 | $0.015/GB | 免费(无出口费!) | 快(全球CDN) |
| AWS S3 | $0.023/GB | $0.09/GB 出口 | 快 |
| 阿里云OSS | 低 | 中 | 快(国内) |
核心优势:R2无出口费! 这是相比S3的最大优势。
安装WP Offload Media插件(推荐)
购买与安装
WP Offload Media插件:$190/年(支持R2)
下载:wp-offload-media.zip
cd wp-content/plugins
unzip wp-offload-media.zip
wp plugin activate wp-offload-media
配置R2凭证
后台 → Settings → WP Offload Media → Storage Providers → Cloudflare R2
1. 获取R2 API Token:
访问:https://dash.cloudflare.com/ → R2 → Create API Token
- Name: wordpress-media
- Permissions: Object Read & Write
- TTL: Never
2. 填入凭证:
Access Key ID: xxxxxxxxxxxxxxxx
Secret Access Key: xxxxxxxxxxxxxxxxxxxxxxxx
Bucket: wp-media
Region: auto(R2无需指定区域)
3. 保存设置
自定义R2集成(无插件)
安装AWS SDK(R2兼容S3 API)
cd wp-content/plugins
mkdir r2-media
cd r2-media
composer require aws/aws-sdk-php
创建插件核心文件
<?php
/**
* Plugin Name: R2 Media Offload
* Description: 将WordPress媒体文件上传到Cloudflare R2
*/
require_once __DIR__ . '/vendor/autoload.php';
use Aws\S3\S3Client;
function get_r2_client() {
return new S3Client([
'version' => 'latest',
'region' => 'auto',
'endpoint' => 'https://<account_id>.r2.cloudflarestorage.com',
'credentials' => [
'key' => R2_ACCESS_KEY,
'secret' => R2_SECRET_KEY,
],
]);
}
// 上传文件到R2
add_filter('wp_handle_upload', 'upload_to_r2');
function upload_to_r2($upload) {
$file_path = $upload['file'];
$file_name = basename($file_path);
$s3 = get_r2_client();
$s3->putObject([
'Bucket' => 'wp-media',
'Key' => 'uploads/' . date('Y/m') . '/' . $file_name,
'Body' => fopen($file_path, 'rb'),
'ACL' => 'public-read',
]);
// 删除本地文件(可选)
unlink($file_path);
// 修改附件URL
$upload['url'] = 'https://<account_id>.r2.cloudflarestorage.com/wp-media/uploads/' . date('Y/m') . '/' . $file_name;
return $upload;
}
配置wp-config.php
// R2凭证
define('R2_ACCESS_KEY', 'xxxxxxxxxxxxxxxx');
define('R2_SECRET_KEY', 'xxxxxxxxxxxxxxxxxxxxxxxxxxxx');
define('R2_BUCKET', 'wp-media');
define('R2_ENDPOINT', 'https://<account_id>.r2.cloudflarestorage.com');
define('R2_URL', 'https://<account_id>.r2.cloudflarestorage.com');
迁移已有媒体库到R2
使用WP-CLI批量迁移
# 安装WP Offload Media CLI扩展
wp package install deliciousbrains/wp-offload-media-wp-cli
# 迁移所有媒体文件到R2
wp offload media migrate --library --bucket=wp-media
# 输出:
# Analyzing media library...
# Found 1234 attachments to migrate.
# Migrating attachment 1/1234: image.jpg... done!
# Migrating attachment 2/1234: document.pdf... done!
# ...
# Migration complete!
自定义迁移脚本(无插件)
add_action('admin_init', 'migrate_existing_media_to_r2');
function migrate_existing_media_to_r2() {
if (!isset($_GET['migrate_to_r2'])) return;
$args = [
'post_type' => 'attachment',
'posts_per_page' => -1,
'post_status' => 'inherit',
];
$attachments = get_posts($args);
$s3 = get_r2_client();
foreach ($attachments as $attachment) {
$file_path = get_attached_file($attachment->ID);
$file_name = basename($file_path);
// 上传到R2
$s3->putObject([
'Bucket' => 'wp-media',
'Key' => 'uploads/' . date('Y/m', strtotime($attachment->post_date)) . '/' . $file_name,
'Body' => fopen($file_path, 'rb'),
'ACL' => 'public-read',
]);
// 更新附件URL
update_post_meta($attachment->ID, '_wp_attached_file', 'uploads/' . date('Y/m') . '/' . $file_name);
echo 'Migrated: ' . $file_name . '<br>';
}
exit;
}
访问:https://example.com/wp-admin/?migrate_to_r2=1
配置R2 + Cloudflare CDN
创建R2 Bucket并启用CDN
1. 访问Cloudflare Dashboard → R2
2. Create Bucket:wp-media
3. Settings → Public Access → Enable
4. Copy Bucket URL:https://<account_id>.r2.cloudflarestorage.com/wp-media
使用Cloudflare CDN加速(无需额外配置)
R2自带Cloudflare CDN!
→ 所有通过R2 URL访问的文件自动走Cloudflare CDN
→ 全球边缘节点缓存
→ 无需配置CNAME
自定义域名(可选)
1. Cloudflare R2 → Bucket Settings → Custom Domains
2. 添加自定义域名:media.example.com
3. Cloudflare自动配置SSL(免费)
现在媒体URL变为:https://media.example.com/uploads/2026/05/image.jpg
删除本地文件(节省服务器空间)
配置WP Offload Media
后台 → Settings → WP Offload Media → Media Offload
- Remove Files from Server: ✅ (上传后删除本地文件)
- Rewrite Attachment URLs: ✅ (附件URL指向R2)
- Force HTTPS: ✅ (强制HTTPS)
验证本地文件已删除
# 检查uploads目录大小
du -sh wp-content/uploads/
# 输出:4.0K(几乎为空,文件已迁移到R2)
# 检查数据库中的附件URL
SELECT guid FROM wp_posts WHERE post_type='attachment' LIMIT 5;
# 输出:https://<account_id>.r2.cloudflarestorage.com/...
故障排除
问题一:上传失败(凭证错误)
# 测试R2连接
aws s3 ls --endpoint-url https://<account_id>.r2.cloudflarestorage.com
# 错误:Unable to locate credentials
# 解决:检查R2_ACCESS_KEY和R2_SECRET_KEY是否正确
问题二:图片不显示(URL错误)
// 调试附件URL
add_action('wp_head', function() {
$upload_dir = wp_upload_dir();
echo '<!-- Upload Base URL: ' . $upload_dir['baseurl'] . ' -->';
});
// 应该输出:https://<account_id>.r2.cloudflarestorage.com/wp-media
问题三:缩略图未生成
// R2不自动生成缩略图!
// 解决:使用WP Offload Media的Image Editing功能
// 或:在本地生成缩略图后再上传到R2
2026年R2 + WordPress趋势
趋势一:R2作为主存储(替代服务器磁盘)
传统架构:
服务器磁盘 → 定期备份到S3
现代架构:
服务器 → 直接上传到R2 → Cloudflare CDN分发
(服务器磁盘只存代码,不存媒体)
趋势二:R2 + Cloudflare Images(智能图片处理)
Cloudflare Images:
- 自动调整尺寸(?width=800)
- 自动转换格式(WebP/AVIF)
- 自动压缩(节省带宽)
URL示例:
https://imagedelivery.net/<account_hash>/<image_id>/width=800
趋势三:R2 + WordPress多站点(共享存储)
// 多站点共享同一个R2 Bucket
// 通过路径区分站点:
// Site 1 → wp-media/site1/uploads/...
// Site 2 → wp-media/site2/uploads/...
define('R2_PATH_PREFIX', 'site' . get_current_blog_id() . '/');
决策建议
- < 10GB媒体 → 服务器本地存储(简单)
- 10GB-100GB → R2(省钱,无出口费)
- > 100GB → R2 + Cloudflare Images(智能处理)
- 多站点 → R2(共享存储,路径隔离)
总结
Cloudflare R2让WordPress媒体存储成本降低90%。2026年,对于图片/视频密集型网站,R2是必选项。
立即行动:注册Cloudflare R2,将你的媒体库迁移到对象存储!
声明:本站所有文章,如无特殊说明或标注,均为本站原创发布。任何个人或组织,在未征得本站同意时,禁止复制、盗用、采集、发布本站内容到任何网站、书籍等各类媒体平台。如若本站内容侵犯了原著者的合法权益,可联系我们进行处理。

评论(0)