Node.js ランタイム

概要

Node.js ランタイムは、アプリケーションのコードと依存関係をインストールして実行するソフトウェア スタックです。ランタイムは app.yamlruntime: nodejs として宣言されています。

runtime: nodejs
env: flex

フレキシブル環境のランタイムは、Docker を使用してビルドされています。Node.js ランタイムは Ubuntu 16.04 がベースとなっていて、Node.js ランタイムのソースコードは GitHub で一般公開されています。

パッケージ マネージャー

デプロイ時に、ランタイムは npm または yarn パッケージ マネージャーを使用し、依存関係をインストールしてアプリケーションを起動します。パッケージ マネージャーは次のロジックに基づいています。

  • デフォルトのパッケージ マネージャーは npm です。
  • yarn.lock ファイルがアプリケーションのルート ディレクトリに存在する場合は、ランタイムは代わりに yarn パッケージ マネージャーを使用します。
  • package-lock.jsonyarn.lock の両方が存在する場合は、エラーが発生してデプロイに失敗します。両方のファイルが必要な場合は、app.yaml ファイルの skip_files セクションにどちらか一方を追加して、使用するパッケージ マネージャーを指定します。

エンジン

Node.js バージョン

デフォルトの Node.js エンジンは最新の LTS リリースにすることを方針としています。アプリケーションの package.json ファイルで engines フィールドを使用することによって、別の Node.js バージョンを指定できます。予期しない破損を回避するために、Node.js バージョンを指定するようにしてください。

次の例では、最新の Node 9 リリースを使用するようにランタイムを構成しています。

{
  "engines": {
    "node": "9.x"
  }
}

engines.node プロパティには semver 範囲を指定できます。これを指定すると、ランタイムによって、semver 範囲に一致する最新バージョンの Node.js がダウンロードおよびインストールされます。一致するものが見つからない場合は、アプリケーションのデプロイが失敗し、ランタイムからエラー メッセージが返されます。

パッケージ マネージャー バージョン

ランタイム イメージでは、最新の Node.js LTS リリースで提供されている最新の yarn リリースおよび npm のリリースを使用する方針としています。

アプリケーションの package.json ファイルで engines フィールドを使用することによって、別のパッケージ マネージャー バージョンを指定できます。この場合、ランタイムは engines フィールドで指定したバージョンのパッケージ マネージャーをデプロイに使用します。

yarnnpm の両方のバージョンを指定した場合は、更新が必要になったとき、デプロイに使用されたパッケージ マネージャーのみが更新されます。アプリケーションのデプロイに実際に使用されていないカスタム バージョンのパッケージ マネージャーについては、デプロイ時間を短縮するためにインストールから除外されます。

次の例では、カスタム バージョンの npm を使用するようにランタイムを構成しています。

{
  "engines": {
    "npm": "5.x"
  }
}

次の例では、カスタム バージョンの yarn を使用するようにランタイムを構成しています。

{
  "engines": {
    "yarn": ">=1.0.0 <2.0.0"
  }
}

engines.npmengines.yarn のいずれのプロパティにも semver 範囲を指定できます。

依存関係

デプロイ時に、ランタイムは npm または yarn パッケージ マネージャーを使用し、npm install または yarn install を実行することで依存関係をインストールします。使用されるパッケージ マネージャーがランタイムでどのように選択されるかの詳細については、パッケージ マネージャーのセクションをご覧ください。

また、Google App Engine での Node.js パッケージの管理の詳細については、Node.js ライブラリの使用をご覧ください。

ネイティブ機能拡張を必要とする Node.js パッケージを使用できるように、次の Ubuntu パッケージが Docker イメージにプリインストールされています。

アプリケーションで追加のオペレーティング システムレベルの依存関係が必要な場合は、このランタイムに基づいてカスタム ランタイムを使用し、適切なパッケージをインストールする必要があります。

アプリケーションの起動

ランタイムは npm start を使用してアプリケーションを起動します。この中で、package.json で指定されたコマンドが使用されます。例:

"scripts": {
  "start": "node app.js"
}

起動スクリプトはウェブサーバーを起動し、それが PORT 環境変数で指定されたポート(一般的には 8080)で HTTP リクエストに応答します。

ランタイムの拡張

標準の Node.js ランタイムを使用して、カスタム ランタイムを作成できます。その場合、まず、gcloud beta app gen-config --custom を使用して基本の Dockerfile ファイルと .dockerignore ファイルを作成します。そして、必要に応じて、このファイルをカスタマイズします。Dockerfile を作成する場合は、app.yamlruntime: nodejs ではなく runtime: custom を指定する必要があるのでご注意ください。

HTTPS プロキシと転送プロキシ

App Engine はロードバランサで HTTPS 接続を終了し、リクエストをアプリケーションに転送します。アプリケーションによっては、元のリクエスト IP とプロトコルを判断する必要があります。ユーザーの IP アドレスは標準の X-Forwarded-For ヘッダーにあります。この情報を必要とするアプリケーションでは、プロキシを信頼するようにウェブ フレームワークを構成する必要があります。

Express.js では、次の trust proxy 設定を使用してください。

app.set('trust proxy', true);

HTTPS 接続を強制する方法については、リクエストの処理方法をご覧ください。

環境変数

次の環境変数が、ランタイム環境によって設定されます。

環境変数 説明
GAE_INSTANCE 現在のインスタンスの名前。
GAE_MEMORY_MB アプリケーション プロセスで使用可能なメモリ量。
GAE_SERVICE アプリケーションの app.yaml ファイルで指定されたサービス名。サービス名が指定されていない場合は、default に設定されます。
GAE_VERSION 現在のアプリケーションのバージョン ラベル。
GOOGLE_CLOUD_PROJECT アプリケーションに関連付けられたプロジェクト ID。この ID は、Google Cloud Platform Console に表示されます。
NODE_ENV アプリがデプロイされている場合、値は production です。
PORT HTTP リクエストを受信するポート。8080 に設定します。

その他の環境変数は app.yaml で設定できます。

メタデータ サーバー

アプリケーションのインスタンスは、ホスト名、外部 IP アドレス、インスタンス ID、カスタム メタデータ、サービス アカウント情報など、インスタンスに関する情報を Compute Engine メタデータ サーバーから取得します。App Engine では、インスタンスごとにカスタム メタデータを設定することはできませんが、プロジェクト単位のカスタム メタデータを設定して、App Engine インスタンスや Compute Engine インスタンスから読み取ることができます。

次のサンプル関数では、メタデータ サーバーからインスタンスの外部 IP アドレスを取得します。

const express = require('express');
const request = require('got');

const app = express();
app.enable('trust proxy');

const METADATA_NETWORK_INTERFACE_URL =
  'http://metadata/computeMetadata/v1/' +
  '/instance/network-interfaces/0/access-configs/0/external-ip';

const getExternalIp = async () => {
  const options = {
    headers: {
      'Metadata-Flavor': 'Google',
    },
    json: true,
  };

  try {
    const {body} = await request(METADATA_NETWORK_INTERFACE_URL, options);
    return body;
  } catch (err) {
    console.log('Error while talking to metadata server, assuming localhost');
    return 'localhost';
  }
};

app.get('/', async (req, res, next) => {
  try {
    const externalIp = await getExternalIp();
    res
      .status(200)
      .send(`External IP: ${externalIp}`)
      .end();
  } catch (err) {
    next(err);
  }
});

const PORT = process.env.PORT || 8080;
app.listen(PORT, () => {
  console.log(`App listening on port ${PORT}`);
  console.log('Press Ctrl+C to quit.');
});
このページは役立ちましたか?評価をお願いいたします。

フィードバックを送信...

Node.js ドキュメントに対応した App Engine フレキシブル環境