Cloud Foundry + Node.js で Hello World

## 概要
- Cloud Foundry 上にシンプルな Node.js アプリケーションをデプロイして動作させる
- Cloud Foundry 環境は [Pivotal Web Services](https://run.pivotal.io/) を使用する

## ソースコード

### ソースコード一覧

```
.
├── Procfile
├── index.js
├── manifest.yml
└── package.json
```

### Procfile 

Procfile にはプログラムの開始コマンドを記述する。
今回は node コマンドで index.js を実行するよう指定している。
コロン左側にはプロセスタイプを指定する。プロセスタイプの web は HTTP 通信を処理することを意味している。

```
web: node index.js
```

参考: [Production Server Configuration \| Cloud Foundry Docs](https://docs.cloudfoundry.org/buildpacks/prod-server.html)

### index.js

HTTP リクエストを受けて結果を返すプログラム。
環境変数 PORT のデフォルト値は 8080 になっている。
ローカル環境でも動作するよう、環境変数が存在しない場合はポート番号に 8080 を指定している。

```javascript
const http = require('http')
http.createServer(function (req, res) {
  let body =
    '<html><body>' + "\n" +
    '<h1>Hello, world.</h1>' + "\n" +
    `<div>process.env.PORT: ${process.env.PORT}</div>\n` +
    '</body></html>' + "\n"
  res.writeHead(200, {'Content-Type': 'text/html'})
  res.end(body)
}).listen(process.env.PORT || 8080)
```

参考: [Tips for Node\.js Applications \| Cloud Foundry Docs](https://docs.cloudfoundry.org/buildpacks/node/node-tips.html)

### manifest.yml 

デプロイするアプリの環境設定ファイル。
random-route に true を指定することで衝突しないホストを自動生成している。

```yaml
---
applications:
- name: my-nodejs-app
  memory: 512M
  instances: 1
  random-route: true
  buildpacks:
  - https://github.com/cloudfoundry/nodejs-buildpack
```

参考:

- [Deploying with App Manifests \| Cloud Foundry Docs](https://docs.cloudfoundry.org/devguide/deploy-apps/manifest.html)
- [Tips for Node\.js Applications \| Cloud Foundry Docs](https://docs.cloudfoundry.org/buildpacks/node/node-tips.html)
- [App Manifest Attribute Reference \| Cloud Foundry Docs](https://docs.cloudfoundry.org/devguide/deploy-apps/manifest-attributes.html)

### package.json

Node.js アプリケーションの設定ファイル。
Node.js のバージョンを指定しておく。

```json
{
  "name": "my-nodejs-app",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "author": "",
  "license": "ISC",
  "engines": {
    "node": "~>12"
  }
}
```

参考:

- [Node\.js Buildpack \| Cloud Foundry Docs](https://docs.cloudfoundry.org/buildpacks/node/index.html)
- [Releases · cloudfoundry/nodejs\-buildpack · GitHub](https://github.com/cloudfoundry/nodejs-buildpack/releases)
- [Tips for Node\.js Applications \| Cloud Foundry Docs](https://docs.cloudfoundry.org/buildpacks/node/node-tips.html)
- [npm\-package\.json \| npm Documentation](https://docs.npmjs.com/files/package.json)

## デプロイ

今回は、 [Pivotal Web Services](https://run.pivotal.io/) の Cloud Foundry 環境にデプロイしている。組織 (Org) とスペース (Space) は事前に作成している。

ログインする。

```
$ cf login -a https://api.run.pivotal.io
API エンドポイント: https://api.run.pivotal.io
(以下略)
```

組織とスペースを設定。

```
$ cf target -o myorg -s development
API エンドポイント   https://api.run.pivotal.io
API バージョン:      2.142.0
ユーザー:            you@example.com
組織:                myorg
スペース:            development
```

デプロイするソースコードを用意する。

```
$ tree
.
├── Procfile
├── index.js
├── manifest.yml
└── package.json

0 directories, 4 files
```

cf push コマンドでアプリケーションをデプロイする。

```
$ cf push
you@example.com としてマニフェストから組織 myorg / スペース development にプッシュしています...
(中略)
アプリが開始するのを待機しています...

名前:                   my-nodejs-app
要求された状態:         started
経路:                   my-nodejs-app-xxxx-xxxxx.cfapps.io
最終アップロード日時:   Sat 30 Nov 08:26:22 JST 2019
スタック:               cflinuxfs3
ビルドパック:           nodejs

タイプ:           web
インスタンス:     1/1
メモリー使用量:   512M
開始コマンド:     node index.js
     状態   開始日時               cpu    メモリー            ディスク          詳細
#0   実行   2019-11-29T23:26:33Z   0.0%   512M の中の 14.2M   1G の中の 82.4M   
```

デプロイしたアプリケーションに curl コマンドでアクセスして動作していることを確認。

```
$ curl https://my-nodejs-app-xxxx-xxxxx.cfapps.io/
<html><body>
<h1>Hello, world.</h1>
<div>process.env.PORT: 8080</div>
</body></html>
```

## 参考資料

- [Getting Started with Pivotal Platform \| Pivotal](https://pivotal.io/jp/platform/pcf-tutorials/getting-started-with-pivotal-cloud-foundry/)
- [Node\.js Buildpack \| Cloud Foundry Docs](https://docs.cloudfoundry.org/buildpacks/node/index.html)
- [Tips for Node\.js Applications \| Cloud Foundry Docs](https://docs.cloudfoundry.org/buildpacks/node/node-tips.html)
- [Deploying with App Manifests \| Cloud Foundry Docs](https://docs.cloudfoundry.org/devguide/deploy-apps/manifest.html)
- [App Manifest Attribute Reference \| Cloud Foundry Docs](https://docs.cloudfoundry.org/devguide/deploy-apps/manifest-attributes.html)
- [Releases · cloudfoundry/nodejs\-buildpack · GitHub](https://github.com/cloudfoundry/nodejs-buildpack/releases)
- [Production Server Configuration \| Cloud Foundry Docs](https://docs.cloudfoundry.org/buildpacks/prod-server.html)
- [Pushing an App \| Cloud Foundry Docs](https://docs.cloudfoundry.org/devguide/deploy-apps/deploy-app.html)
- [npm\-package\.json \| npm Documentation](https://docs.npmjs.com/files/package.json)