deno deployでWebサイトを公開する方法4種

[deno deploy](https://deno.com/deploy)はDeno社が公式で提供する、Deno向けのエッジコンピューティングサービスです。

https://deno.com/deploy

# deno deployの特徴

#### TypeScriptをトランスパイルなしでそのまま実行

deno deployはDenoの実行基盤を流用して構築されているため、TypeScriptやwasmを直接実行することができます。事前のビルドステップがないため、CI/CD等でビルド構成を設定する必要がありません。

#### GitHub連携

GitHubを使用している場合、GitHub Appsをリポジトリにインストールすると、push時に自動でデプロイされます。またプルリクエストが開かれた場合はプレビュー用のURLが発行されます。
自分が試した感じだと、pushしてから本番環境に反映されるまで3秒から5秒ほどで結構早いです。

GitHubリポジトリ上のファイルは`Deno.readTextFile()`などを使ってローカルファイルのように読むことができます。これの何がうれしいかというと、ローカルファイル向けの既存のDeno向けライブラリがそのままdeploy上でも動きます。

#### エッジコンピューティング

最近流行りのエッジコンピューティング技術が使用されています。サーバーは世界各地のデータセンターで実行され、負荷に合わせて自動でスケールします。
日本では、東京リージョンと大阪リージョンが存在します。

#### Denoを使用したローカル開発

ローカル開発にはDenoをインストールして使用します。deno deployの環境は基本的にDenoの最新バージョンと互換性があり、Denoに搭載されているAPIの大部分がdeployでも動きます。

#### 公式サポート

例えば、Node.jsのホスティング環境をNode.jsが公式で提供することは今までありませんでした。
一方、deno deployはDeno社が公式で提供するサービスです。将来的にDenoの最新バージョンに追従していくことが確実なうえ、OSSであるDenoプロジェクトのマネタイズという面でも、プロジェクトの安定性が見込めると思います。

## deno deployの使い方

deno deployでWebサイトを公開する方法は**4種類**あります。

4種類をどのように使い分けるかについては、

- 簡単なテストプロジェクトのデプロイ→[①playgroundのオンラインエディタを使用する方法](#playgroundを使用してデプロイする方法)
- 通常のDenoプロジェクトのデプロイ→[②GitHub Appsを使う方法](#github-apps連携を使ってデプロイする方法)
- GitHub Actionsでビルドしてからデプロイ→[③Github Actions+deployctlを使う方法](#github-actions--deployctlを使ってデプロイする方法)
- GitHubを使用せずローカルからデプロイ→[④CLIでdeployctlを使う方法](#cliでdeployctlを使ってデプロイする方法)

のように使い分けていくとよさそうです。
それぞれどのような手順でデプロイするのか見てみましょう。

※いずれの方法にもGitHubアカウントによるサインインが必要です。GitHubアカウントが無い方は、まず取得しましょう。

### ①playgroundを使用してデプロイする方法

1. https://dash.deno.com/new にアクセスします。
1. GitHubアカウントとの連携を求められるので、ログインします。
  ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/678625/e1a650bc-74e5-3863-f040-4146e1893d24.png)
1. New Projectという画面が表示されたら、右側の`Play`というボタンをクリックします。
  ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/678625/92abf67f-2c2f-b079-a6c8-5c75e93c376a.png)
1. すると、ランダムなプロジェクト名が設定されたHello Worldサーバーが作成されます。画面の左側がエディタで、右側が実稼働しているWebサイトになります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/678625/c13ea74b-43e1-bf5f-6074-2667c358bfb9.png)

1. エディタの内容を編集してctrl-sすると、右側の本番環境に即時反映されます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/678625/442afb35-fa65-c7e3-08d3-7ede84641eab.png)


playgroundは公開して他人と共有することができます。共有するには、playground画面の上部からsettingsを開き、Make Publicボタンをクリックします。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/678625/b8e4f444-0b33-1621-1dc6-fc225d1a947e.png)

以上の手順で公開したplaygroundはこちらから見ることができます。→ https://dash.deno.com/playground/fine-crab-75

この方法は簡単なコードを書いて他人と共有したいときに便利です。

### ②GitHub Apps連携を使ってデプロイする方法

通常のWebサイトをデプロイする方法です。この方法が一番メジャーな方法です。

1. デプロイしたいGitHubリポジトリを用意します。
1. GitHubリポジトリに、サーバーのエントリポイントとなるファイルを用意します。
    ```ts:サーバーの例
    import { serve } from "https://deno.land/std@0.140.0/http/server.ts";
    serve(() => new Response("Hello world")); // Hello Worldサーバー
    ```
1. https://dash.deno.com/new にアクセスします。
1. GitHubアカウントとの連携を求められるので、ログインします。
1. New Projectという画面が表示されたら、左上の`Deploy from GitHub repository`欄に必要な情報を入力します。途中でファイルを選択する場面がありますが、選ぶのは先ほど作成したエントリポイントのファイルです。
1. お好きなプロジェクト名を入力して、`Link`をクリックします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/678625/16817e9b-c997-b9b2-b258-cce5137f1609.png)
1. GitHub Appsを使った連携を許可するかどうか尋ねられた場合は、許可して連携します。

これでセットアップは完了です。以後、GitHubリポジトリにpushした場合は何もしなくても自動で本番環境に反映されます。
また、プルリクエストを開いた場合は本番環境には反映されず、プレビュー版のデプロイが作成されます。

ローカル開発はDenoを使用して行います。

```shell
> deno run --allow-net ./serve.ts
```

### ③Github Actions + deployctlを使ってデプロイする方法

②で紹介した方法だと、デプロイ前にビルドすることができません。
例えばmarkdownで書かれたファイルをHTMLに変換してからサイトに公開したい場合、GitHubへpushしてからdeno deployへdeployするまでの間に、[Hugo](https://gohugo.io/)などのSSGツールを使ってビルドを挟みたい場合があります。

そういう時のために、GitHub Actions内からdeployできる[deployctl](https://deno.com/deploy/docs/deployctl)というツールが存在します。


1. デプロイしたいGitHubリポジトリを用意します。
1. https://dash.deno.com/new にアクセスします。
1. GitHubアカウントとの連携を求められるので、ログインします。
1. New Projectという画面が表示されたら、左上の`Deploy from GitHub repository`欄に必要な情報を入力します。
1. ここで、ブランチ選択後に`via`欄から`GitHub Actions`を選択します。(重要)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/678625/5ed77eeb-557e-7b0d-a80f-52250e652d10.png)

1. するとGitHub Actionsのworkflowが表示されます。この内容をコピーします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/678625/0255052e-716d-6dc3-e569-b5f8ba9c3e3f.png)

1. GitHubリポジトリに`/.github/workflows/deploy.yml`というファイルを作成し、先ほどコピーした内容をペーストします。
1. workflowファイルの内容はGitHub Actionsで実行されます。workflowファイル内の`TODO: add a build step here`の場所にビルドステップを追加することで、任意のSSGツールを使用できます。

ビルドステップの追加例は[公式ブログ](https://deno.com/blog/hugo-blog-with-deno-deploy)でも解説されているので、参考にしてみてください。

### ④CLIでdeployctlを使ってデプロイする方法

GitLabなど、GitHub以外でソース管理している場合は、上記の方法は使えません。その場合は、

1. deployctlコマンドをインストール
1. 環境変数を設定
1. deployctlコマンドを叩いて本番環境にdeploy

という手順を踏むことで任意の環境からdeployできます。なお、deno deployにログインするためには、現状ではGitHubアカウントが必須となっています。

1. denoのインストール
  deployctlをインストールするために、まずはDenoをインストールします。インストール方法については https://deno.land/#installation を参照してください。
1. deployctlコマンドのインストール
  [公式ドキュメント](https://deno.com/deploy/docs/deployctl#deployctl-cli)を参考にdeployctlをインストールします。
    ```shell
    deno install --allow-read --allow-write --allow-env --allow-net --allow-run --no-check -r -f https://deno.land/x/deploy/deployctl.ts
    ```
1. https://dash.deno.com/new にアクセスします。
1. GitHubアカウントとの連携を求められるので、ログインします。
1. New Projectという画面が表示されたら、右下の`+Empty Project`をクリックします
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/678625/146c517b-edab-724d-811d-049c41f2279a.png)
1. https://dash.deno.com/user/access-tokens にアクセスし、新しいアクセストークンを作成します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/678625/68d02d75-95c0-0832-5d25-9811528dd00f.png)
1. 作成したアクセストークンをコピーして、環境変数`DENO_DEPLOY_TOKEN`に設定します。
1. `deployctl deploy`コマンドを使用して、Webサイトを本番環境にデプロイします。
    コマンドの使い方については[公式ドキュメント](https://deno.com/deploy/docs/deployctl#usages)を参照してください。

アクセストークンはシークレット情報なので、外部に漏れないように配慮する必要があります。

## まとめ

deno deployでWebサイトを公開する方法は4種類あります。

1. playgroundのオンラインエディタを使用する方法
2. GitHub Appsを使う方法
3. Github Actions+deployctlを使う方法
4. CLIでdeployctlを使う方法

使い方を色々試すなら①、一般的なプロジェクトなら②、SSGしたい場合は③、GitHub以外からデプロイする場合は④、というように使い分けるとよさそうです。