Cloud Foundry（IBM Cloud）でNode.jsの最新バージョンを利用する


IBM CloudのCloud Foundry、Node.jsの新しいバージョンを使うときに少し工夫が必要でした。

`ibmcloud cf push`でデプロイした際のログから辿ってると、IBM Cloud側の対応状況と、Cloud Foundry側のドキュメントの対応状況が若干異なるみたいですね。

Cloud Foundryって元々独立してたけどIBMに吸収されたとかでしたっけ...

## まずはNode.jsのバージョン指定無しの場合

特にバージョンを指定せずにデプロイすると以下のような警告が出ました。

デフォルトがNode.js v10系らしいです。流石に古いので警告が出てます。

```
   Downloading app package...
   Downloaded app package (635.9K)
   -----> IBM SDK for Node.js Buildpack v4.6-20210305-2036
          Based on Cloud Foundry Node.js Buildpack 1.7.44
   -----> Installing binaries
          engines.node (package.json): unspecified
          engines.npm (package.json): unspecified (use default)
          **WARNING** Node version not specified in package.json or .nvmrc. See: http://docs.cloudfoundry.org/buildpacks/node/node-tips.html
          Attempting to install: 10.24.0
   -----> Installing node 10.24.0
          Copy [/tmp/buildpacks/73dd77c5b9dcb13eb662490e81ac9cf2/nodejs/dependencies/aaf73e55b7db4c30b2da7af326e10a54/node_10.24.0_linux_x64_cflinuxfs3_db472e29.tgz]
          **WARNING** node 10.x.x will no longer be available in new buildpacks released after 2021-04-01.
          See: https://github.com/nodejs/Release
          Using default npm version: 6.14.11
   -----> Installing yarn 1.22.10
```

## package.jsonに追記してNode.jsのバージョンを指定

`**WARNING** Node version not specified in package.json or .nvmrc.`と` **WARNING** node 10.x.x will no longer be available in new buildpacks released after 2021-04-01.`とのことなので、バージョンをあげてみます。

package.jsonにenginesを追記します。

```package.json
省略

  "engines": {
    "node": "14.x"
  },

省略
```

ちなみに、v15にしようとしたら怒られました。まだ対応してない模様です。 

> `**ERROR** Unable to install node: no match found for 15.x in [10.23.3 10.24.0 12.20.2 12.21.0 14.15.5 14.16.0]`

## `manifest.yml`にbuildpacksの指定すると比較的新しいバージョンが利用できる

執筆時点だとNode.js v15.12.0が最新ですが、enginesに15.xを指定したら↑で書いたエラーになりました。

ただ、Cloud Foundryのnodejs-buildpackを指定することで最新が利用できそうです。

> [cloudfoundry/nodejs-buildpack](https://github.com/cloudfoundry/nodejs-buildpack/releases)

ここをみると、執筆時点でNode.js v15.11.0まで対応してそうでした。
（若干最新ではないけどほぼ最新に追従してそう）

先ほどはまでは、`manifest.yml`にbuildpacksの指定をしないでデプロイしてましたが、以下のように指定するとbuildpacksに`https://github.com/cloudfoundry/nodejs-buildpack`を指定すると最新バージョンの利用できます。（現状だとNode.js v15.11.0まで対応）

```manifest.yml
---
applications:
 - name: n0bisuke-testapp
   random-route: true
   memory: 64M
   buildpacks:
    - https://github.com/cloudfoundry/nodejs-buildpack
```

これでv15系が使えるのでpackage.jsonでも指定します。

```package.json
省略

  "engines": {
    "node": "15.x"
  },

省略
```

ちなみに、`process.versions`でバージョン情報を確認できるので、以下のようなコードを書きました。

```server.js
const express = require('express')
const app = express()
 
app.get('/', function (req, res) {
  res.send(JSON.stringify(process.versions))
})
const port = process.env.PORT || 3000
 
app.listen(port)
```

デプロイして確認したらこんな感じでした。

> ![スクリーンショット 2021-03-24 13.58.00.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/35387/a403959d-eae4-486b-0cd8-6b9ae20b28a0.png "スクリーンショット 2021-03-24 13.58.00.png")

v15.11.0になってますね。

## 補足: 別の指定の仕方

IBM Cloud側のドキュメントにある指定の仕方だと以下のように記述できますが、こちらを利用した場合適用されたのがv15.7.0と若干ですが古いみたいでした。

> https://cloud.ibm.com/docs/cloud-foundry?topic=cloud-foundry-deploy_apps&locale=ja

```manifest.yml
---
applications:
 - name: n0bisuke-testapp
   random-route: true
   memory: 64M
   buildpack: nodejs_buildpack
```

先ほどは`buildpacks`でURL指定でしたが、こちらは`buildpack`で名前指定という違いですね。

## 注意点: デプロイ時間が長いかも

体感的にですが、buildpacksを指定したデプロイの方がデプロイ時間が長い気がしています。

v15系でもv14系でも大丈夫って場合はbuildpacksを指定しないで14系を使った方がデプロイは早いかもしれません。

指定しないとSwiftのビルドパックなど関係なさそうなものもダウンロードしてそうなログが表示されるのですが、こっちの方がデプロイ時間が短い気がしているという謎状態 （体感なのでちゃんと調べてません。）

## まとめ

現時点のバージョンですが以下のような対応状況でした。

* 全く指定無し
	* v10になる
* enginesに指定
	* v14系まで利用可能
* manifest.jsonでビルドパック指定
	* buildpacksでURL指定: v15.11.0まで利用可能
	* buildpackで名前指定: v15.7.0まで利用可能