Overview
Deno を CloudRun で動作させるまでをまとめました。
How to get started
インストール手順 に則って Deno で簡単な Web サーバーを起動します。
Install Deno
Mac では brew が使えるらしいのでとりあえず brew を使って deno を入れます。
$ brew install deno $ deno --version deno 1.0.2 v8 8.4.300 typescript 3.9.2
そしてドキュメントにも記載されてる通り簡単な動作確認は以下
$ deno run https://deno.land/std/examples/welcome.ts Download https://deno.land/std/examples/welcome.ts Warning Implicitly using master branch https://deno.land/std/examples/welcome.ts Compile https://deno.land/std/examples/welcome.ts Welcome to Deno 🦕
Sample web server
次に簡単な Web サーバーを立ち上げて見ます。
Deno で Web server を立ち上げるためには直で https://deno.land/std@0.53.0/http/server.ts
を import して使うのが簡単のようです。import に https://deno.land/...
のフォーマットで書いておけば、実行時に依存関係を取得できます。
お試しで動かしたいケースにおいては最適ですね。
Go みたいに自動的に取得してくれたりしないのかな。。。
import { serve } from "https://deno.land/std@0.53.0/http/server.ts"; const port = 8080; const s = serve({ port: port }); console.log("Starting server port: ", port); for await (const req of s) { req.respond({ body: "Hello World\n" }); }
このコードを書いた後 Deno を起動する。
$ deno run --allow-net ./main.ts Download https://deno.land/std@0.53.0/http/server.ts Download https://deno.land/std@0.53.0/encoding/utf8.ts Download https://deno.land/std@0.53.0/io/bufio.ts Download https://deno.land/std@0.53.0/testing/asserts.ts Download https://deno.land/std@0.53.0/async/mod.ts Download https://deno.land/std@0.53.0/http/_io.ts Download https://deno.land/std@0.53.0/async/deferred.ts Download https://deno.land/std@0.53.0/async/delay.ts Download https://deno.land/std@0.53.0/async/mux_async_iterator.ts Download https://deno.land/std@0.53.0/textproto/mod.ts Download https://deno.land/std@0.53.0/http/http_status.ts Download https://deno.land/std@0.53.0/io/util.ts Download https://deno.land/std@0.53.0/fmt/colors.ts Download https://deno.land/std@0.53.0/testing/diff.ts Download https://deno.land/std@0.53.0/bytes/mod.ts Download https://deno.land/std@0.53.0/path/mod.ts Download https://deno.land/std@0.53.0/path/win32.ts Download https://deno.land/std@0.53.0/path/posix.ts Download https://deno.land/std@0.53.0/path/common.ts Download https://deno.land/std@0.53.0/path/separator.ts Download https://deno.land/std@0.53.0/path/interface.ts Download https://deno.land/std@0.53.0/path/glob.ts Download https://deno.land/std@0.53.0/path/_constants.ts Download https://deno.land/std@0.53.0/path/_util.ts Download https://deno.land/std@0.53.0/path/_globrex.ts Compile file:///$pathToDir/myFirstDeno/main.ts Starting server port: 8080 $ curl localhost:8080 Hello World # console.log で指定した内容が出力されます。
import で https://deno.land/std@0.53.0/http/server.ts
のようにバージョンを指定して import する方法が少し気になったので調べてみます。
Deno の serve のドキュメントを読むと以下のようになっています。
/** * Create a HTTP server * * import { serve } from "https://deno.land/std/http/server.ts"; * const body = "Hello World\n"; * const s = serve({ port: 8000 }); * for await (const req of s) { * req.respond({ body }); * } */
https://deno.land/std/http/server.ts
というバージョンなし import で依存を解決してます。
試しに標準の http モジュールを使って実行してみました。
import serve from "https://deno.land/std/http/server.ts"
に書き換えただけです。実行結果は以下。
$ deno run --allow-net main.ts Download https://deno.land/std/http/server.ts Warning Implicitly using master branch https://deno.land/std/http/server.ts Download https://deno.land/std/encoding/utf8.ts Download https://deno.land/std/io/bufio.ts Download https://deno.land/std/testing/asserts.ts Download https://deno.land/std/async/mod.ts Download https://deno.land/std/http/_io.ts Warning Implicitly using master branch https://deno.land/std/testing/asserts.ts #略
Warning Implicitly using master branch
という警告が出るようになってしまいました。
これは一体どういうことなのだろう?標準ライブラリでもバージョニングをいれることが推奨されているのかもしれないですが、ちょっとまだお作法がよくわかっていません。
もしかして暗黙的に master を使っていると master はよく変更が加わるもので、何かのアップデートがあった時にコードが壊れてしまう可能性があるから暗黙的に master の標準ライブラリを使用するのは避けるべきなのかもしれません、とか考えてたら書いてありました。
Denoでは、バージョン管理も簡単、importしているURLに@^${バージョン番号}を追加するだけです。
ファイルレベルでバージョン管理されてるのは確かに良さそうです。
この辺ルールを決めないと自由度上がりすぎてプロジェクト全体で特定バージョンを使いたいユースケースに対応し切れないですが、そういうことを嫌った結果なのかもしれませんね。知らんけど。
(...node_modules はデカイしいやだよね)
また、別にdeps.tsというファイルを用意し、そこでバージョンを一括管理することもできます。
deps.ts
なんてものもあるんですね。これは別の機会に調べてみようと思います。
VSCode plugin
Deno の VSCode のプラグインがすでに登場してました。Install extentions
で検索するとわかりますが、いくつか Deno 関連のプラグインが出てきます。
僕は現時点(20200527) で公式の以下を使ってみることにしました。
Configuration に記載されてる設定の property を Setting.json に追加します。
// deno "deno.enable": true, "deno.alwaysShowStatus": true, "deno.importmap": null, "deno.autoFmtOnSave": "", //未実装なのでなし
Node Modules
最初にサーバーを起動した時に Download...
と表示されたように deno は import に宣言しておけば、local に存在しない依存は実行時に自動で取得してくれるっぽいです。
(なんとなく Go Modules みたいだなと感じました。)
node のエコシステムは deno には必要ないんですね。
(感動)
Working on docker
Deno の動作をローカルで確認したところで次に Docker で Deno を動かします。
Deno の公式の Dokcer イメージは以下です。
https://github.com/hayd/deno-docker
Build & Run
Dockerfile を用意します。
FROM hayd/alpine-deno:1.0.2 EXPOSE 1993 # The port my application listen to. WORKDIR /app USER deno COPY deps.ts . RUN deno cache deps.ts COPY . . RUN deno cache main.ts CMD ["run", "--allow-net", "main.ts"]
$ docker build -t emahiro-deno . Sending build context to Docker daemon 8.192kB Step 1/9 : FROM hayd/alpine-deno:1.0.2 1.0.2: Pulling from hayd/alpine-deno c9b1b535fdd9: Already exists 052c7836b622: Pull complete 9460a82e0a88: Pull complete eef61d161c0b: Pull complete Digest: sha256:1a759550e5cc76980f5ebc3a599c79e6fc6e5cc34827083edd1225a25ac4dd12 Status: Downloaded newer image for hayd/alpine-deno:1.0.2 ---> 8f192534bc9d Step 2/9 : EXPOSE 8080 ---> Running in 13d038204325 Removing intermediate container 13d038204325 ---> 31e5525dd8a6 Step 3/9 : WORKDIR /app ---> Running in 7f5d89735bd2 Removing intermediate container 7f5d89735bd2 ---> b9b01c114460 Step 4/9 : USER deno ---> Running in 90aea4eca3b0 Removing intermediate container 90aea4eca3b0 ---> 9bba107b8b99 Step 5/9 : COPY deps.ts . ---> a05bfbd4d8a7 Step 6/9 : RUN deno cache deps.ts ---> Running in 24022494bfd8 Compile file:///app/deps.ts Removing intermediate container 24022494bfd8 ---> c4517e93e4d6 Step 7/9 : COPY . . ---> c03cb478f6df Step 8/9 : RUN deno cache main.ts ---> Running in 8df5fad63cbd Download https://deno.land/std@0.53.0/http/server.ts Download https://deno.land/std@0.53.0/encoding/utf8.ts Download https://deno.land/std@0.53.0/io/bufio.ts Download https://deno.land/std@0.53.0/testing/asserts.ts Download https://deno.land/std@0.53.0/async/mod.ts Download https://deno.land/std@0.53.0/http/_io.ts Download https://deno.land/std@0.53.0/textproto/mod.ts Download https://deno.land/std@0.53.0/http/http_status.ts Download https://deno.land/std@0.53.0/io/util.ts Download https://deno.land/std@0.53.0/fmt/colors.ts Download https://deno.land/std@0.53.0/testing/diff.ts Download https://deno.land/std@0.53.0/async/deferred.ts Download https://deno.land/std@0.53.0/async/delay.ts Download https://deno.land/std@0.53.0/async/mux_async_iterator.ts Download https://deno.land/std@0.53.0/path/mod.ts Download https://deno.land/std@0.53.0/bytes/mod.ts Download https://deno.land/std@0.53.0/path/win32.ts Download https://deno.land/std@0.53.0/path/posix.ts Download https://deno.land/std@0.53.0/path/common.ts Download https://deno.land/std@0.53.0/path/separator.ts Download https://deno.land/std@0.53.0/path/interface.ts Download https://deno.land/std@0.53.0/path/glob.ts Download https://deno.land/std@0.53.0/path/_globrex.ts Download https://deno.land/std@0.53.0/path/_constants.ts Download https://deno.land/std@0.53.0/path/_util.ts Compile file:///app/main.ts Removing intermediate container 8df5fad63cbd ---> 7c68bae2e695 Step 9/9 : CMD ["run", "--allow-net", "main.ts"] ---> Running in 8b34e2020b18 Removing intermediate container 8b34e2020b18 ---> 8d26b2c23903 Successfully built 8d26b2c23903 Successfully tagged emahiro-deno:latest $ docker run --name deno-app -d -it --rm -p 8080:8080 emahiro-deno {$ContainerID} $ docker ps -a CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 7651ddde92f8 emahiro-deno "deno run --allow-ne…" About a minute ago Up About a minute 0.0.0.0:1993->1993/tcp deno-app
コンテナが起動した状態で curl でHTTPリクエストを送ってみます。
$ curl localhost:8080 Hello World
Docker を使ってローカルでサーバーを起動させることができました。
Deploy to Cloud Run
Cloud Run にデプロイしてみます。
デプロイ手順は こちら
Regionの指定
Cloud Run のリージョンは既に東京があるので東京( asia-northeast1
) を使用します。これは gcloud run deploy
時に --region
フラグで指定しもいいし、 gcloud
コマンドの設定を追加しても大丈夫です。
ref: https://cloud.google.com/run/docs/locations?hl=ja
# gcloud の設定を確認 $ gcloud config list # 東京リージョンの設定 $ gcloud config set run/region asia-northeast1
ref: gcloud config コマンドのリファレンス
Setting Cloud Build
Cloud Run を使うには Cloud Build を有効にする必要があります。
Cloud Build, Cloud Run, Container Registry, and Resource Manager API を有効にします。
ビルド済みの既存のイメージからコンテナを作成しない場合は Container Registry は必要ありません。
Cloud Build は API を有効にしたのち Cloud Build を使うサービスに 権限 を付与しないといけないので Cloud Build > 設定 で Cloud Run 管理者を有効にします。Cloud Run を有効にすると追加でサービスアカウントへの権限付与も求められるので権限を付与します。
最終的には以下のようになります。
Deploy
コンテナを Cloud Registry に登録
$ gcloud builds submit --tag gcr.io/$PROJECT_NAME/emahiro-deno:latest
Deploy to Cloud Run
gcloud run deploy hello-deno --image gcr.io/$PROJECT_NAME/emahiro-deno --region asia-northeast1 --platform managed --allow-unauthenticated Deploying container to Cloud Run service [hello-deno] in project [$PROJECT_NAME] region [asia-northeast1] ✓ Deploying new service... Done. ✓ Creating Revision... ✓ Routing traffic... ✓ Setting IAM Policy... Done. Service [hello-deno] revision [hello-deno-00001-geh] has been deployed and is serving 100 percent of traffic at https://hello-deno-$HASH.a.run.app
--platform
: 実行環境のPFを指定する。 managed or gke or kubernetes が入ります。基本的には managed で良いです。(ただし region の option が必須。gcloud config set run/region していない場合は)
--allow-unauthenticated
: 認証付きリクエストにするかどうか。認証必須の場合は --no-allow-unauthenticated
になります。
ref: gcloud run deploy のリファレンス
その他
price
気になったので価格表だけ久しぶりに調べました。まぁ遊ぶくらいなら無料枠で余裕かなと思います。
Cloud Build
Cloud Run