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

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

元記事はこちら

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