Google App Engine を安く Node.js で使う

  • 28
    いいね
  • 0
    コメント

重要な追記

2017年3月に GCE の無料枠が拡大され、f1-micro インスタンスが無料枠に入りました

しかし GAE の仕様変更もあり、この記事の方法は既に陳腐化しています。例えば vm: true は deprecated で、 env: flex とする必要があります。

また、この記事の方法でマシンタイプを極小にしようとしても、小さすぎる指定がエラーになるようになってしまいました。このあたりは app.yaml のリファレンスに詳しいです。

色々試してみましたが、エラーを避けつつ f1-micro インスタンスで起動する方法は見つかりませんでした。

一方で、2016年6月頃にこの記事の方法でデプロイしたアプリケーションは f1-micro で動き続けており、課金額もほぼ無料になっていました。

以下の内容は2016年6月時点のものとしてお読みください。

tl;dr

無料で可能な限り安く Node.js アプリを動かしたい!!!!ので app.yaml を書きなおした。

先人の知恵

しかし

先人の知恵そのままに Node.js アプリをデプロイしようとすると

ERROR: (gcloud.preview.app.deploy) Error Response: [400] VM-based automatic scaling should NOT have the following parameter(s): [min_pending_latency, max_idle_instances]

と怒られてしまった。どうやら言語によって app.yaml に定義すべき内容の仕様が微妙に違うらしい。

automatic_scaling まわりの設定項目が異なるのをおわかりいただけるだろうか……

調べてみると、 GAE for Node.js は Python や PHP のそれらと違った仕組みで動いているらしい。

既存のPythonやGoランタイムとは違って、利用できるのはApp Engine上の真のPaaSではない。代わりに、Node.jsは彼らのApp Engine「flexible environment」内で実行される。このflexible environmentは、Google Compute Engine上に構築されたManaged VMに基づいている。

Google App EngineでNode.jsのベータ版が利用可能に より引用)

つまり、 GAE for Node.js は実質 GAE に見せかけて GCE で動いている。言い換えると、 GAE for Node.js は無料枠(28 インスタンス時間 / 日)を使うことができない。現実は残酷である。

ならば

Node.js 用の仕様に沿ってケチケチに設定する必要がある。

PHP や Python では使用するインスタンスクラスを app.yaml で明示的に指定でき、そのデフォルト値は最小インスタンスである f1-micro を含む F1 になっている。

これに対し、Node.js (というか前述の Managed VM 環境)では cpumemory_gb の値を指定し、その設定に応じて自動的にインスタンスクラスが選択される。これらのデフォルト値はそれぞれ .51.3 であり、このままでは g1-small が使用されてモリモリ課金されてしまう。

app.yaml に設定するリソース容量はアプリケーションが使用できるリソース容量と思われ、インスタンスのスペックのギリギリ下だと一段階上のインスタンスが選択されてしまう。従って、 f1-micro のスペックを大幅に下回るように設定する。

そして

試行錯誤の結果、このような app.yaml になり、つつがなく f1-micro で動くようになった。最高!!!!!!

app.yaml
runtime: nodejs
vm: true
skip_files:
  - ^(.*/)?.*/node_modules/.*$
threadsafe: true
automatic_scaling:
  min_num_instances: 1
  max_num_instances: 2
  cool_down_period_sec: 60
  cpu_utilization:
    target_utilization: .7
resources:
  cpu: .2
  memory_gb: .15

しかし無料枠はお預け。現実は無情である。