将线上的 Cloudflare R2(对象存储,用于存图片等文件)和 D1(数据库,用于存文章标题、内容等元数据)的数据导入到本地,以确保开发环境与生产环境一致,主要涉及两个部分:
同步 R2 中的文件(图片等)
同步 D1 中的数据库记录,并更新文件链接
下面我将为你提供一个完整、分步的指南。
核心概念:D1 与 R2 的关系
在你的应用中:
Cloudflare D1 存储的是结构化数据,比如你的 posts 表,里面有 id, title, content, slug 以及一个 image_url 字段。
Cloudflare R2 存储的是对象文件,也就是用户上传的图片。D1 数据库中的 image_url 字段,其值就是指向 R2 中对应图片文件的 URL。
要做到数据一致,我们必须同时处理这两部分。
准备工作:安装与登录
确保你已经安装了 Cloudflare 的命令行工具 wrangler,并且已经登录。
Generated bash
安装/更新 wrangler
npm install -g wrangler
登录你的 Cloudflare 账户
wrangler login
步骤一:从线上的 R2 Bucket 下载所有图片
首先,我们需要把生产环境 R2 Bucket 里的所有图片文件下载到本地的一个文件夹里。
找到你的 R2 Bucket 名称:登录 Cloudflare 控制台,进入 "R2" 页面,找到你的存储桶名称,例如 my-blog-images-prod。
在本地创建一个文件夹:用于存放下载下来的图片。
Generated bash
mkdir -p local-r2-data
IGNORE_WHEN_COPYING_START
content_copy
download
Use code with caution.
Bash
IGNORE_WHEN_COPYING_END
使用 wrangler 下载文件:运行以下命令,它会将指定 R2 Bucket 中的所有文件下载到你刚创建的本地文件夹中。
Generated bash
语法: wrangler r2 bucket download <BUCKET_NAME> [LOCAL_DIRECTORY]
示例:
wrangler r2 bucket download my-blog-images-prod ./local-r2-data
IGNORE_WHEN_COPYING_START
content_copy
download
Use code with caution.
Bash
IGNORE_WHEN_COPYING_END
执行后,local-r2-data 文件夹里现在就有了所有线上的图片。
步骤二:为本地图片创建一个本地服务
现在图片在本地了,但你的本地应用需要通过一个 HTTP URL (如 http://localhost:8788/images/xxx.png) 来访问它们,而不是通过文件路径。我们有两种主流方案:
方案 A:使用本地 S3 兼容服务器 (推荐,更接近真实环境)
使用像 MinIO 这样的工具,可以在本地模拟一个和 R2 (S3-compatible) 一样的对象存储服务。
使用 Docker 运行 MinIO (最简单的方式):
Generated bash
docker run \
-p 9000:9000 \
-p 9001:9001 \
--name minio \
-e "MINIO_ROOT_USER=my-access-key" \
-e "MINIO_ROOT_SECRET=my-secret-key" \
minio/minio server /data --console-address ":9001"
IGNORE_WHEN_COPYING_START
content_copy
download
Use code with caution.
Bash
IGNORE_WHEN_COPYING_END
这会在本地 9000 端口启动 MinIO 服务,9001 端口启动管理后台。
访问 http://localhost:9001,用上面设置的 my-access-key 和 my-secret-key 登录。
在 MinIO 中创建 Bucket 并上传文件:
在 MinIO 管理后台,创建一个 Bucket,例如 dev-bucket。
进入这个 Bucket,点击 "Upload",然后将 local-r2-data 文件夹里的所有文件上传上去。
配置本地应用: 在你的本地开发环境 (.dev.vars 或 wrangler.toml 的 dev 部分) 中,需要配置环境变量,告诉应用去连接本地的 MinIO 而不是线上的 R2。
Generated ini
.dev.vars
R2_BUCKET_NAME="dev-bucket"
S3_ENDPOINT="http://127.0.0.1:9000" # MinIO 地址
S3_ACCESS_KEY_ID="my-access-key"
S3_SECRET_ACCESS_KEY="my-secret-key"
你需要修改你的应用代码,在开发模式下使用这些S3客户端配置
IGNORE_WHEN_COPYING_START
content_copy
download
Use code with caution.
Ini
IGNORE_WHEN_COPYING_END
方案 B:使用简单的静态文件服务器 (简单快捷)
如果不想配置 MinIO,可以把图片文件夹当作静态资源,用一个简单的服务器来托管。
将图片文件夹放在 public 目录下:
将下载好的 local-r2-data 文件夹移动到你项目根目录下的 public 文件夹中,并重命名为 uploads。你的目录结构看起来像:public/uploads/image1.jpg。
修改本地开发服务器配置:
Cloudflare Workers 本地开发服务器 wrangler dev 默认会托管 public 目录下的静态资源。所以,现在你可以通过 http://localhost:8787/uploads/image1.jpg 访问到这个图片 (端口号以你的实际情况为准)。
步骤三:同步 D1 数据库并更新 URL
这是最关键的一步,我们需要把线上的数据库内容导到本地,并把里面的 image_url 从线上地址改成我们本地的地址。
找到你的 D1 数据库名称:在 wrangler.toml 文件中找到生产环境的 database_name。例如 prod-db。
从线上 D1 导出数据: 运行命令,将线上数据库导出为一个 .sql 文件。
Generated bash
语法: wrangler d1 export <DATABASE_NAME> --output=./dump.sql
示例:
wrangler d1 export prod-db --output=./prod_dump.sql
IGNORE_WHEN_COPYING_START
content_copy
download
Use code with caution.
Bash
IGNORE_WHEN_COPYING_END
修改 SQL 文件中的 URL:
打开 prod_dump.sql 文件。你需要批量替换 image_url 字段的值。
原 URL 格式: https://<your-r2-public-url>/image1.jpg
目标 URL 格式 (方案A-MinIO): http://localhost:9000/dev-bucket/image1.jpg
目标 URL 格式 (方案B-静态服务器): /uploads/image1.jpg (使用相对路径更佳)
你可以使用任何文本编辑器的“查找和替换”功能。例如,将 https://<your-r2-public-url>/ 替换为 /uploads/。
将修改后的数据导入本地 D1:
首先,确保你的 wrangler.toml 中为本地开发环境配置了 D1 数据库。
Generated toml
wrangler.toml
[[d1_databases]]
binding = "DB"
database_name = "local-dev-db"
database_id = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx" # 本地数据库ID
preview_database_id = "..." # 预览环境ID
IGNORE_WHEN_COPYING_START
content_copy
download
Use code with caution.
Toml
IGNORE_WHEN_COPYING_END
然后,执行导入命令,将修改后的 SQL 文件导入到本地 D1 数据库。
Generated bash
语法: wrangler d1 execute <DATABASE_NAME> --local --file=./path/to/sql
示例:
wrangler d1 execute local-dev-db --local --file=./prod_dump.sql
IGNORE_WHEN_COPYING_START
content_copy
download
Use code with caution.
Bash
IGNORE_WHEN_COPYING_END
--local 标志是关键,它确保了数据是写入本地的 .wrangler/state/d1 目录下的 SQLite 文件,而不是线上数据库。
总结与推荐流程
对于大多数项目,方案 B (静态文件服务器) 是最快、最简单的。
完整流程回顾 (使用方案 B):
下载 R2 文件:
wrangler r2 bucket download my-blog-images-prod
移动并重命名文件:
将下载好的文件夹移动到项目 public 目录下,并重命名为 uploads。
导出线上 D1 数据:
wrangler d1 export prod-db --output=./prod_dump.sql
修改 SQL 文件:
打开 prod_dump.sql,全局查找替换图片 URL 的前缀。例如,将 https://pub-xxxxx.r2.dev/ 替换为 /uploads/。
导入到本地 D1:
wrangler d1 execute local-dev-db --local --file=./prod_dump.sql
启动本地开发:
wrangler dev
现在,你的本地开发环境就拥有了和线上几乎完全一致的数据,图片和数据库记录都已同步并正确链接。