[{"data":1,"prerenderedAt":10},["ShallowReactive",2],{"public:public\u002Fcontent\u002Fdocs\u002Fcloudflare-r2":3},{"slug":4,"title":5,"description":6,"draft":7,"updated":8,"html":9},"cloudflare-r2","Cloudflare R2","Write pg_dump backups to an R2 bucket and give Verestore a read-only R2 API token scoped to that bucket.",false,null,"\u003Ch1>Cloudflare R2\u003C\u002Fh1>\n\u003Cblockquote>\n\u003Cp>Verified against the provider&#39;s documentation, not against a live account.\u003C\u002Fp>\n\u003C\u002Fblockquote>\n\u003Cp>A provider snapshot disappears with the account that holds it; a dump in a bucket you control is the copy that survives, and Verestore proves it restores.\u003C\u002Fp>\n\u003Ch2>1. Write dumps to R2\u003C\u002Fh2>\n\u003Cp>R2 speaks the S3 API at \u003Ccode>https:\u002F\u002F&lt;account-id&gt;.r2.cloudflarestorage.com\u003C\u002Fcode> (or \u003Ccode>https:\u002F\u002F&lt;account-id&gt;.eu.r2.cloudflarestorage.com\u003C\u002Fcode> for a bucket in the EU jurisdiction). The signing region is always \u003Ccode>auto\u003C\u002Fcode>. With a separate read-write token for your backup job:\u003C\u002Fp>\n\u003Cpre>\u003Ccode class=\"language-sh\">pg_dump --format=custom --no-owner &quot;$DATABASE_URL&quot; \\\n  | aws --endpoint-url &quot;https:\u002F\u002F$R2_ACCOUNT_ID.r2.cloudflarestorage.com&quot; --region auto \\\n      s3 cp - &quot;s3:\u002F\u002Facme-backups\u002Forders\u002Forders-$(date -u +%Y-%m-%dT%H-%M).dump&quot;\n\u003C\u002Fcode>\u003C\u002Fpre>\n\u003Cp>Verestore accepts \u003Ccode>pg_dump\u003C\u002Fcode> custom format (\u003Ccode>-Fc\u003C\u002Fcode>) or plain SQL, optionally gzipped. The format is detected from the content, not the file extension.\u003C\u002Fp>\n\u003Ch2>2. Create a read-only R2 API token\u003C\u002Fh2>\n\u003Cp>R2 API tokens are scoped to buckets, not to prefixes. Use a \u003Cstrong>dedicated bucket per database\u003C\u002Fstrong> so the token can read nothing else.\u003C\u002Fp>\n\u003Col>\n\u003Cli>In the Cloudflare dashboard, open \u003Cstrong>R2\u003C\u002Fstrong> and create an \u003Cstrong>API token\u003C\u002Fstrong> (check the provider&#39;s current documentation for the exact menu).\u003C\u002Fli>\n\u003Cli>Name it \u003Ccode>verestore-reader\u003C\u002Fcode>.\u003C\u002Fli>\n\u003Cli>Permission: \u003Cstrong>Object Read only\u003C\u002Fstrong>.\u003C\u002Fli>\n\u003Cli>Scope: apply it to the specific bucket \u003Ccode>acme-backups\u003C\u002Fcode> only.\u003C\u002Fli>\n\u003Cli>Create the token and copy the \u003Cstrong>Access Key ID\u003C\u002Fstrong> and \u003Cstrong>Secret Access Key\u003C\u002Fstrong> shown for S3 clients. The secret is shown once.\u003C\u002Fli>\n\u003C\u002Fol>\n\u003Cp>Verestore only lists objects under the prefix (\u003Ccode>ListObjectsV2\u003C\u002Fcode>) and reads \u003Ccode>orders\u002F*\u003C\u002Fcode>, pinned to the listed ETag. It never writes or deletes.\u003C\u002Fp>\n\u003Ch2>3. Add the target in Verestore\u003C\u002Fh2>\n\u003Cul>\n\u003Cli>S3 endpoint: \u003Ccode>https:\u002F\u002F&lt;account-id&gt;.r2.cloudflarestorage.com\u003C\u002Fcode> (or the \u003Ccode>.eu.\u003C\u002Fcode> form)\u003C\u002Fli>\n\u003Cli>Region: \u003Ccode>auto\u003C\u002Fcode> (or leave it empty: it is filled from the endpoint)\u003C\u002Fli>\n\u003Cli>Bucket: \u003Ccode>acme-backups\u003C\u002Fcode>\u003C\u002Fli>\n\u003Cli>Prefix: \u003Ccode>orders\u002F\u003C\u002Fcode>\u003C\u002Fli>\n\u003Cli>Access key ID and secret access key: from the token\u003C\u002Fli>\n\u003C\u002Ful>\n",1794290783589]