denoflare で Cloudflare R2 をカスタムドメイン公開する

# Cloudflare R2 とは

公式ブログを読むべし

- [Cloudflare R2ストレージの発表 - 高速で信頼できるオブジェクトストレージ、エグレス料金なし](https://blog.cloudflare.com/ja-jp/introducing-r2-object-storage-ja-jp/)
- [オブジェクトストレージに新たな希望：R2がオープンデータ版に](https://blog.cloudflare.com/ja-jp/r2-open-beta-ja-jp/)

# denoflare とは

> - [skymethod/denoflare: Develop, test, and deploy Cloudflare Workers with Deno.](https://github.com/skymethod/denoflare)
> - [Overview · Denoflare](https://denoflare.dev/)
>   - `Develop, test, and deploy Cloudflare Workers with Deno`
>   - `Denoflare is still under active initial development (pre 1.0), but is completely open-source and can be used as is.`

# denoflare インストール

macOS で確認します。

```shell
% defaults read loginwindow SystemVersionStampAsString
12.4
```

最初に v0.5.1 をインストールしようとするとエラーになったので、v0.5.1 の前に v0.3.2 をインストールすると問題なく完了しました。

```shell
% deno install --unstable --allow-read --allow-net --allow-env --allow-run --name denoflare --force \
https://raw.githubusercontent.com/skymethod/denoflare/v0.3.2/cli/cli.ts
✅ Successfully installed denoflare
/Users/kyouhei/.deno/bin/denoflare
ℹ️  Add /Users/kyouhei/.deno/bin to PATH
    export PATH="/Users/kyouhei/.deno/bin:$PATH"
    
% deno install --unstable --allow-read --allow-net --allow-env --allow-run --name denoflare --force \
https://raw.githubusercontent.com/skymethod/denoflare/v0.5.1/cli/cli.ts
Check https://raw.githubusercontent.com/skymethod/denoflare/v0.5.1/cli/cli.ts
✅ Successfully installed denoflare
/Users/kyouhei/.deno/bin/denoflare
```

インストールが完了し、コマンド実行できることを確認します。

```shell
% denoflare version                                                                                  
0.5.1
% denoflare --help 
denoflare 0.5.1

USAGE:
    denoflare <command> <args> <options>

COMMANDS:
    serve      Run a Cloudflare worker script in a local Deno web server
    push       Upload a Cloudflare worker script to Cloudflare
    tail       View a real-time stream of logs from a published Cloudflare worker
    site       Develop and deploy a static docs site to Cloudflare Pages
    analytics  Dump stats via the Cloudflare GraphQL Analytics API
    cfapi      Call the Cloudflare REST API
    r2         Manage Cloudflare R2 storage using the S3 compatibility API
    version    Dump cli version

For command-specific help: denoflare <command> --help
```

# 事前準備ガイド

[R2 Public Read · Denoflare](https://denoflare.dev/examples/r2-public-read) に沿って進めます。

- Cloudflare アカウント - https://dash.cloudflare.com/sign-up
- [ドメインセットアップ](https://developers.cloudflare.com/dns/zone-setups/) - カスタムドメインに必要
- [R2 有効化](https://developers.cloudflare.com/r2/get-started/#purchase-r2) - 支払い方法の設定が必要
  - 10 GB / 月の無料枠があるので、すぐには課金される心配はない

> https://developers.cloudflare.com/r2/platform/pricing/
>
> ![image-20220611004653833](https://cdn.jsdelivr.net/gh/kyouheicf/image@master/uPic/image-20220611004653833.png)

# R2 バケット作成

ダッシュボードで作成します。

![image-20220611010208287](https://cdn.jsdelivr.net/gh/kyouheicf/image@master/uPic/image-20220611010208287.png)

# API トークン作成

https://dash.cloudflare.com/profile/api-tokens から API トークンを作成します。

![image-20220611004937391](https://cdn.jsdelivr.net/gh/kyouheicf/image@master/uPic/image-20220611004937391.png)

「Edit Cloudflare Workers」のテンプレートを使います。

![image-20220611005032116](https://cdn.jsdelivr.net/gh/kyouheicf/image@master/uPic/image-20220611005032116.png)

カスタムドメイン利用に必要な以下の権限を追加します。

![img](https://denoflare.dev/images/custom-domains-permissions.png)

その後、API トークンが発行されますが、一度しか表示されないため、メモします。

![image-20220611005733725](https://cdn.jsdelivr.net/gh/kyouheicf/image@master/uPic/image-20220611005733725.png)

# カスタムドメインで公開

変数を確認し、セットします。

```shell
export ACCOUNT_ID='YOUR_ACCOUNT_ID'
export MY_DOMAIN='YOUR_DOMAIN_NAME'
export MY_BUCKET='YOUR_BUCKET_NAME'
export API_TOKEN='YOUR_API_TOKEN'
```

以下のコマンドで `push` するだけで、Workers と R2 が Binding され、カスタムドメイン適用の上で公開されます。

設定を修正したい場合は、`flags` 等を変更して再度 `push` すれば、反映されます。

```shell
denoflare push https://raw.githubusercontent.com/skymethod/denoflare/v0.5.1/examples/r2-public-read-worker/worker.ts \
   --name ${MY_BUCKET}-public-read \
   --r2-bucket-binding bucket:${MY_BUCKET} \
   --text-binding flags:listDirectories \
   --custom-domain ${MY_BUCKET}.${MY_DOMAIN} \
   --account-id ${ACCOUNT_ID} \
   --api-token ${API_TOKEN}
```

以下のログ表示が確認できます。

```shell
bundling xxx-public-read into bundle.js...
bundle finished (process) in 557ms
computed bindings in 1ms
putting module-based worker xxx-public-read... (12.8kb) (3.8kb compressed)
put script xxx-public-read in 1725ms
ensuring xxx.example.com points to xxx-public-read...
bound worker to custom domain in 502ms
```

`https://${MY_BUCKET}.${MY_DOMAIN}` にアクセスすると、ディレクトリリスティングのページが確認できます。

![image-20220611014202613](https://cdn.jsdelivr.net/gh/kyouheicf/image@master/uPic/image-20220611014202613.png)

画像もアクセスして確認できました。

![FT-syldaQAI99-S](https://cdn.jsdelivr.net/gh/kyouheicf/image@master/uPic/FT-syldaQAI99-S.jpg)

# まとめ

いわゆる Route 53 + CloudFront + S3 と同等の構成を Cloudflare でも実現できました。

しかも無料でここまで構成できるので、誰でも体験できるようになっています。

さらには Cloudflare Access を使って認証を設定したり、Firewall Rules で国別アクセス制御を設定できます。
（denoflare の Workers スクリプト内で IP アクセス制御等を行うこともできますが、Cloudflare の機能を使って制御するのもおすすめです。）

Cloudflare R2 を Open Beta のうちから触っておくと、色々と想像が膨らませられそうです。