Parse Server - GCE ディプロイ編

開発用Parse Serverをローカルに立ててみましたが、デバッグに制約があり使い勝手があまりよくないので、Quick botchでGCEのインスタンス上にサーバーを立ててみました。

全てGoogle Cloud PlatformのWebコンソールから操作していますが、もちろんgcloudコマンドラインツールからも操作可能です。インスタンス起動後はローカルサーバーを立てる手順と同じになります。BootイメージにはUbuntu14.04を使用しました。

# GCEインスタンス作成

## 1. プロジェクト作成

任意のプロジェクト名（ここではParse Server）でプロジェクトを作成します。
![33a8dccd-5dfb-3f0d-4191-2479caae6bae.png](https://qiita-image-store.s3.amazonaws.com/0/49088/9fd0a3ef-28a8-72a7-60db-1552c6695940.png)

## 2. VMインスタンス作成

メニュー＞Compute Engine、もしくはダッシュボードのTake a VM quickstartを選択します。

![66c54f1c-cd6b-bd9f-bae3-b91f2c82d299.png](https://qiita-image-store.s3.amazonaws.com/0/49088/3b92909d-2013-0e6d-90e6-397ce4f9206a.png)

Create instanceボタンを押します。

![16082b2a-afb6-2f10-932a-0a0cb328bd92.png](https://qiita-image-store.s3.amazonaws.com/0/49088/18c027c8-ef7e-7cb9-8913-3bb8015cd16c.png)


インスタンス名、ゾーン、マシンタイプ、Bootディスクはお好みで。f1-microをusゾーンに立てた場合、10GBのディスクと合わせても月にUS$7.00程度です。使用しない間は停止しておくこともできます。FirewallのAllow HTTP trafficはチェックしておきます。

![36f0db26-7d0a-9e56-07f3-8daec74f1f21.png](https://qiita-image-store.s3.amazonaws.com/0/49088/72c350f1-2fe4-dc86-1ce4-5273345a6eba.png)

## 3. 使用ポートのファイアウォールルール作成

今回、defaultポート番号の1337をそのまま使用しました。ソースフィルタで接続元を限定可能、許可対象プロトコルとポートは"tcp:1337"、名前、説明、ターゲットタグは任意です。

![b76be12d-f8a9-f386-5717-72cc4a07c448.png](https://qiita-image-store.s3.amazonaws.com/0/49088/157aaa61-4748-b2c4-90b3-4d352930e178.png)

SSH接続でWeb端末を開いたら、あとはローカルホストと同様に必要なものをインストールしていきます。

![3fcf2f30-d207-89b0-0262-35907e592e69.png](https://qiita-image-store.s3.amazonaws.com/0/49088/1c085310-c4e5-7444-35ac-0953bf87211b.png)

IPアドレスはデフォルトでEphemeralになっており、典型的には再起動の都度、動的に変わってしまいます。productionサーバーでなくとも、メニュー＞Networking＞External IP addressesページからStaticに変更しておいたほうが無難です。

# Parse Serverインストール

## 0. 前提条件

```
$ sudo apt-get update
$ sudo apt-get install git
$ python -V
Python 2.7.6
```

**[Installing Node.js via package manager](https://nodejs.org/en/download/package-manager/)**

```
$ curl -sL https://deb.nodesource.com/setup_4.x | sudo -E bash -
$ sudo apt-get install -y nodejs
$ node --version
v4.2.6
$ sudo apt-get install -y build-essential
```

**[Install MongoDB](https://docs.mongodb.org/manual/installation/)**

```
$ sudo apt-key adv --keyserver hkp://keyserver.ubuntu.com:80 --recv EA312927
$ echo "deb http://repo.mongodb.org/apt/ubuntu trusty/mongodb-org/3.2 multiverse" | sudo tee /etc/apt/sources.list.d/mongodb-org-3.2.list
$ sudo apt-get update
$ sudo apt-get install -y mongodb-org
```

## 1. サンプルParse Serverインストール

```
$ git clone https://github.com/ParsePlatform/parse-server-example.git
$ cd parse-server-example/
$ sudo apt-get install libkrb5-dev
$ npm install
```

libkrb5-devをインストールしておかないと、以下のエラーが起きると思います。

```
> kerberos@0.0.18 install /home/tatsu/parse-server-example/node_modules/kerberos
> (node-gyp rebuild) || (exit 0)
make: Entering directory `/home/tatsu/parse-server-example/node_modules/kerberos/build'
  CXX(target) Release/obj.target/kerberos/lib/kerberos.o
In file included from ../lib/kerberos.cc:1:0:
../lib/kerberos.h:5:27: fatal error: gssapi/gssapi.h: No such file or directory
 #include <gssapi/gssapi.h>
                           ^
compilation terminated.
make: *** [Release/obj.target/kerberos/lib/kerberos.o] Error 1
make: Leaving directory `/home/tatsu/parse-server-example/node_modules/kerberos/build'
gyp ERR! build error 
gyp ERR! stack Error: `make` failed with exit code: 2
gyp ERR! stack     at ChildProcess.onExit (/usr/lib/node_modules/npm/node_modules/node-gyp/lib/build.js:270:23)
gyp ERR! stack     at emitTwo (events.js:87:13)
gyp ERR! stack     at ChildProcess.emit (events.js:172:7)
gyp ERR! stack     at Process.ChildProcess._handle.onexit (internal/child_process.js:200:12)
gyp ERR! System Linux 3.19.0-43-generic
gyp ERR! command "/usr/bin/nodejs" "/usr/lib/node_modules/npm/node_modules/node-gyp/bin/node-gyp.js" "rebuild"
gyp ERR! cwd /home/tatsu/parse-server-example/node_modules/kerberos
gyp ERR! node -v v4.2.6
gyp ERR! node-gyp -v v3.0.3
gyp ERR! not ok 
```

環境変数を設定します。index.jsに直接書いても構いません。

```
$ export APP_ID=YourParseApplicationId
$ export MASTER_KEY=YourMasterKey
$ export DATABASE_URI=mongodb://localhost:27017/your_db_name
$ export FACEBOOK_APP_ID=YourFacebookAppId
```

サーバーを起動します。

```
$ npm start
> parse-server-example@1.0.0 start /home/tatsu/parse-server-example
> node index.js
parse-server-example running on port 1337.
```

ローカルから以下の要求を投げてresultが返ってくれば正常です。

```
curl -X POST \
  -H "X-Parse-Application-Id: YourParseApplicationId" \
  -H "Content-Type: application/json" \
  -d '{}' \
  http://XXX.XXX.XXX.XXX:1337/parse/functions/hello
```

**補足1**
今回は開発用としていますが、もちろんprojuction/staging用としてGCEを使用してもよいわけです。ググったらnodeサーバーのデーモン起動するチュートリアルが出てきましたので参考までに載せておきます。

[How To Set Up a Node.js Application for Production on Ubuntu 14.04](https://www.digitalocean.com/community/tutorials/how-to-set-up-a-node-js-application-for-production-on-ubuntu-14-04)

こちらにはGoogle App Engineにディプロイする手順が書かれています。合わせて載せておきます。

[Deploying Parse server to Google App Engine](https://medium.com/google-cloud/deploying-parse-server-to-google-app-engine-6bc0b7451d50#.lyyg2kdsk)

**補足2**
iOSアプリについてですが、iOS9ではApp Transport Securityが有効になっているので、馴れっこかとは思いますがサーバーのIPアドレスを許可してあげないと以下のようなエラーが起きますよね。

```
[Error]: The resource could not be loaded because the App Transport Security policy requires the use of a secure connection. (Code: 100, Version: 1.12.0)
```

NSExceptionDomainsではIPアドレスを指定できないので、いまのところNSAllowsArbitraryLoadsでATSを無効にせざるを得ませんね。

```Info.plist
<key>NSAppTransportSecurity</key>
     <dict>
         <key>NSAllowsArbitraryLoads</key>
         <true/>
     </dict>
```

[App Transport Security and IP addresses in iOS9](http://stackoverflow.com/questions/30903923/app-transport-security-and-ip-addresses-in-ios9)