Deno Deploy デプロイ方法 3通り (+ 1) & ちょっと引っかかったこと

## [Deno Deploy](https://deno.com/deploy) とは

Deno 社が提供している、Deno 専用ホスティングサービスです。

ホスティングサービスとは、平たく言えばレンタルサーバ的なもの。任意のサーバプログラム (各ホスティングサービスが対応している言語や環境に限る) を、ネットにつながったマシン上で動かし続けてくれます。

自宅にサーバを立てれば当然好き放題できますが、ホスティングサービスならマシン本体や電源設備などの管理は心配なし。その分、通常は料金が生じます (サービスによっては無料枠もある)。

が、Deno Deploy はなんと[それなりの性能で、しかも期間制限なしで無料！](https://deno.com/deploy/pricing)(ただし記事執筆時点でのことで、将来どうなるかは分かりません。) あと、GitHub アカウント連携が前提で、追加のアカウント作成などの手間が無いのも嬉しいポイントです。

## デプロイ方法

### 0. Playground

簡単なコードをブラウザ上でお試しできる方法です。

ダッシュボード右上の 'New Playground' を押下。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/540894/5661d557-f006-4a00-acae-2d169427f314.png)

すると、コードエディタが開き、サンプルコードが。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/540894/19edcd74-34ae-4031-b628-9a42d806327e.png)

ここに書いて保存したードは、即座に Deno Deploy 上で動作し初め、画面右上の URL からアクセスして試すことが可能です。

TS、JS はもちろん。TSX や JSX も試すことができるようです。まずはお試し、というなら、ブラウザ上だけでもすぐに始めることができます。

ちなみに、プロジェクト名はランダムに生成されたものが付与されます。(上のスクリーンショットでは `fresh-crow-29` でした。)

### 1. CLI `deployctl`

ローカル上のファイルを、コマンドラインからデプロイする方法です。

まずは [`deployctl` をインストール](https://docs.deno.com/deploy/manual/deployctl/#install-deployctl)。

```sh
deno install -gArf jsr:@deno/deployctl

deployctl -h

# 私の場合、bash でなく fish だからか、パスが通っていなかったので、以下で無理やり実行しました
~/.deno/bin/deployctl -h
```

次に、適当な作業場所で HTTP サーバを実装。

```sh
mkdir work
cd work

# 好みのテキストエディタで
vim main.ts
```

:::note warn
ホーム上に `~/main.ts` と作って進めようとしたところ、次の `deployctl deploy` コマンドで、ホームディレクトリ下のファイルを危うく**全てアップロードしてしまいそうになりました。** 事故防止のため、必ず作業場所を作って進めましょう。
:::

今回は Playground のサンプルと同じで。

```main.ts
Deno.serve((req: Request) => new Response("Hello World"));
```

あとは `deployctl` でデプロイ。**ダッシュボードの準備は不要です。**

```sh
ls
# main.ts

deployctl deploy --project=akuad-helloworld --entrypoint=main.ts
```

:::note warn
ここで入力したプロジェクト名が既に誰かに使われている場合、`error: APIError: This project name is already in use.` とエラーになります。別のプロジェクト名に変更しましょう。

ちなみに、[サンプル通りの `helloworld`](https://docs.deno.com/deploy/manual/deployctl/#deploy) は使用中でした。
:::

初めてのデプロイ、または久々のデプロイ (セッション有効期限切れ？) の場合、ブラウザで認証画面が開きます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/540894/479ad5bf-30d9-48a1-9ddb-48c77553e2cb.png)

ダッシュボードを見ると、プロジェクトが作られているのが分かります。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/540894/17b048f9-a985-4c47-8f6d-3a5cb84a4c5d.png)

この URL にアクセスして確認してみましょう。

```sh
curl https://akuad-helloworld.deno.dev/
# Hello World
```

同じプロジェクト名で再度デプロイすれば、同じプロジェクトにインスタンスを追加することになります。

```sh
# ソース編集等の後、同じコマンドで再デプロイ
deployctl deploy --project=akuad-helloworld --entrypoint=main.ts
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/540894/c3cdc987-481a-470a-b413-8be6af3bba85.png)

:::note
Prod とバッジがあるのは、Production としてセットされているインスタンスです。Production としてセットされているインスタンスには、`<project-name>.deno.dev` という URL でアクセスできます。

Production をセットするには、ダッシュボードで当該インスタンスのメニュー「︙」から 'Promote to Production'。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/540894/ff33b02c-ff9b-40bb-b07a-efdb00a2810f.png)

もしくは、デプロイ時に `--prod` オプションを付けます。

```sh
~/.deno/bin/deployctl deploy --project=akuad-helloworld --entrypoint=main.ts --prod
```

:::

### 2. GitHub リポジトリ + ブラウザ上の操作

GitHub リポジトリ上のソースコードを、ブラウザ上の操作からデプロイする方法です。

ダッシュボード右上の 'New Projects' を押下。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/540894/0a7f4de1-653b-4098-b88a-53b70d24c460.png)

連携している GitHub アカウントと、そこのリポジトリを選択。

:::note
デフォルトでは、どのリポジトリへのアクセス権も付与されていないので、恐らくリポジトリが表示されません。Modify GitHub Permissions から、アクセスを許可するリポジトリを選択します。
:::

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/540894/5ff84737-ee5d-44c5-9710-010a2bd3fa11.png)

リポジトリを選択すると、下にメニューが出てきます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/540894/8953acd5-6dd4-44ff-ba0a-47030b889f21.png)

- Production Branch
  - デプロイ対象ブランチ
- Project Name
  - プロジェクト名, ダッシュボード上の表示や URL に反映される
  - その下のチェックボックス 'Just link the repo ...' は「3. GitHub Actions」にて使用
- Framework Preset
  - 使用するフレームワーク, 例えば Fresh, Next.js, Vite など
  - フレームワークなしでプレーンの場合は None
- Install Step
  - 例えば `npm install`
- Build Step
  - ビルドコマンド
- Root directory
  - Entrypoint を実行する際のカレント？
- Include files
  - デプロイに含むファイル
- Exclude files
  - デプロイに含まないファイル
- Entrypoint
  - どのファイルが起点かを指定
  - ローカル上で `deno run --allow-... <file.ts>` するときに指定するファイルをここに指定する

各設定をして 'Deplot Project' でデプロイ完了。Production Branch に対して Push や Merge があると、自動で再デプロイされます。

:::note warn
私がこの方法を試したとき、Root directory: `src`、Entrypoint: `src/main.ts` としたところ、カレントが `src` になっていなかったらしく、`serveDir` で上手くファイルを読んでくれませんでした。

解決方法はわからず、諦めて下の 3. GitHub Actions の方法で進めました。
:::

### 3. GitHub Actions

文字通り、GitHub 上のソースコードを、GitHub Actions からデプロイする方法です。

まずは「1. GitHub リポジトリ + ブラウザ上の操作」と同じく、'New Project' を押下。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/540894/0a7f4de1-653b-4098-b88a-53b70d24c460.png)

GitHub アカウント、リポジトリ、ブランチを選択、プロジェクト名を入力、今度は 'Just link the repo ...' のチェックを入れて 'Create Project' を押下。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/540894/828044fc-67a4-4151-9101-ea6944065c1d.png)

ここからは GitHub リポジトリの操作に移ります。先で指定したリポジトリに、デプロイのための GitHub Actions ワークフローを作成します。

こちらも[公式でサンプルのワークフローが紹介されています](https://docs.deno.com/deploy/manual/ci_github/#github-actions)。公式リファレンスはいいぞ。

(以下、ちょっと解説加えたり、一部削ったりしたもの)

```.github/workflows/deploy.yml
name: Deno Deploy
on:
  push:
    branches: main

jobs:
  deploy:
    runs-on: ubuntu-latest

    permissions:
      id-token: write # これのおかげで手動でのトークン設定とか無くて済む！
      contents: read

    steps:
      - name: Clone repository
        uses: actions/checkout@v4

      - name: Build step
        run: deno task build # ビルドとかが必要なら適宜追加

      - name: Upload to Deno Deploy
        uses: denoland/deployctl@v1
        with:
          project: <your-project-name> # 先のダッシュボードで設定したプロジェクト名
          entrypoint: main.ts # 起動の起点となる (実行する) ソース
          root: . # ここをカレントとして entrypoint が実行される
```

:::note warn
`entrypoint:` の指定は、root からの相対パスなので注意。

例えば、起点となるソースが `src/main.ts` で、カレントを `src` にしてから起動したいときは、`entrypoint: main.ts`、`root: src` というようになる。
:::

あとは、ワークフローで指定したトリガ `on:` が発生すれば、デプロイが実施されます。

:::note
他、`denoland/deployctl` の引数 (`with:`) は、公式の [`action/README.md` を参照](https://github.com/denoland/deployctl/blob/main/action/README.md#inputs)。
:::

以上、終了。なんと、手動でのトークン設定といったようなことはしません！

:::note
ちなみに、トリガ `on:` で全ての push に対してデプロイするようにしたとき、デフォルトブランチ (main) 以外でも当然デプロイされますが、デフォルトブランチのときだけ Production としてデプロイされたことがあったような･･･。
:::

## おわり

環境変数とトークンをいじくって、といった手間なく、とても快適に自動デプロイ (CD) を組むことができました。

[Deno Deploy ホームページページトップに 'Hassle-free' =手間いらず とあるように](https://deno.com/deploy) (記事執筆時点)、とにかく出だしから手間が少なく、ハードルが低いです。