Ubuntu14.04で解析アプリを解析サーバーに移行する方法
序章
Parseは、2013年からFacebookが所有するサービスプラットフォームとしてのモバイルバックエンドです。 2016年1月、Parseは、ホストされているサービスが2017年1月28日に完全にシャットダウンすることを発表しました。
幸い、Parseは、 ParseServerと呼ばれるホスト型サービスのAPIと互換性のあるオープンソースAPIサーバーもリリースしました。 Parse Serverは活発に開発されており、大規模な開発者コミュニティを引き付ける可能性があります。 Node.jsとMongoDBを実行しているさまざまな環境にデプロイできます。
このガイドでは、既存のParseアプリケーションをUbuntu14.04で実行されているParseServerのスタンドアロンインスタンスに移行することに焦点を当てています。 無料の証明書を提供する新しい認証局であるLet’sEncryptが提供する証明書を使用して、すべての接続にTLS/SSL暗号化を使用します。 DigitalOceanとUbuntu14.04に固有の詳細がいくつか含まれていますが、最近のDebianから派生したGNU/Linuxディストリビューションを実行しているシステムに広く適用できるはずです。
警告:この手順は、ユーザー向けの本番アプリで試す前に、まずアプリの開発バージョンまたはテストバージョンでテストすることを強くお勧めします。 また、このガイドを公式の移行ドキュメントと併せて読むことを強くお勧めします。
前提条件
このガイドは、 Ubuntu14.04で解析サーバーを実行する方法に基づいています。 以下が必要です。
- ルート以外の
sudo
ユーザーで構成されたUbuntu14.04サーバー - Node.js 5.6.x
- MongoDB 3.0.x
- サーバーを指すドメイン名
- 移行する解析アプリ
- Let’sEncrypt証明書を使用してSSLでインストールおよび構成されたNginx。 Ubuntu 14.04でLet’sEncryptを使用してNginxを保護する方法では、プロセスについて説明します。
ターゲットサーバーには、アプリのすべてのデータを処理するのに十分なストレージが必要です。 Parseはデータを圧縮するため、ホストされているアプリで使用されるストレージスペースの少なくとも10倍のストレージスペースをプロビジョニングすることを公式に推奨しています。
ステップ1-移行用にMongoDBを構成する
Parseは、既存のアプリケーション用の移行ツールを提供します。 これを利用するには、MongoDBを外部接続に開き、Let’sEncryptのTLS/SSL証明書のコピーで保護する必要があります。 fullchain1.pem
とprivkey1.pem
を/etc/ssl
の新しいファイルに結合することから始めます。
- sudo cat /etc/letsencrypt/archive/domain_name/{fullchain1.pem,privkey1.pem} | sudo tee /etc/ssl/mongo.pem
Let’s Encrypt証明書を更新した後、上記のコマンドを繰り返す必要があります。 Let’s Encrypt証明書の自動更新を構成する場合は、この操作を含めることを忘れないでください。
mongo.pem
がmongodbユーザーによって所有されており、その所有者のみが読み取り可能であることを確認してください。
- sudo chown mongodb:mongodb /etc/ssl/mongo.pem
- sudo chmod 600 /etc/ssl/mongo.pem
次に、nano
(または選択したテキストエディタ)で/etc/mongod.conf
を開きます。
- sudo nano /etc/mongod.conf
ここでは、いくつかの重要な変更を行います。
まず、net:
セクションでbindIp
行を探し、127.0.0.1
を0.0.0.0
に変更して、すべてのアドレスをリッスンするようにMongoDBに指示します。 この下に、SSL構成を同じセクションに追加します。
# network interfaces
net:
port: 27017
bindIp: 0.0.0.0
ssl:
mode: requireSSL
PEMKeyFile: /etc/ssl/mongo.pem
次に、# security
で、クライアント認証を有効にします。
# security
security:
authorization: enabled
最後に、移行ツールでは、failIndexKeyTooLong
パラメーターをfalse
に設定する必要があります。
setParameter:
failIndexKeyTooLong: false
注:空白は、YAMLに基づくMongoDB構成ファイルで重要です。 構成値をコピーするときは、インデントを保持していることを確認してください。
終了してファイルを保存します。
mongod
サービスを再起動する前に、admin
ロールを持つユーザーを追加する必要があります。 実行中のMongoDBインスタンスに接続します。
- mongo --port 27017
管理者ユーザーを作成して終了します。 sammy を目的のユーザー名に、passwordを強力なパスワードに置き換えてください。
use admin
db.createUser({
user: "sammy",
pwd: "password",
roles: [ { role: "userAdminAnyDatabase", db: "admin" } ]
})
exit
mongod
サービスを再起動します。
- sudo service mongod restart
ステップ2–解析からアプリケーションデータを移行する
リモートでアクセス可能なMongoDBインスタンスができたので、Parse移行ツールを使用してアプリのデータをサーバーに転送できます。
移行ツールのMongoDBクレデンシャルを構成する
まず、新しい管理者ユーザーとローカルで接続します。
- mongo --port 27017 --ssl --sslAllowInvalidCertificates --authenticationDatabase admin --username sammy --password
以前に設定したパスワードを入力するように求められます。
接続したら、アプリのデータを保存するデータベースの名前を選択します。 たとえば、Todoというアプリを移行する場合は、todo
を使用できます。 また、parseというユーザー用に別の強力なパスワードを選択する必要があります。
mongo
シェルから、このユーザーにdatabase_name
へのアクセスを許可します。
- use database_name
- db.createUser({ user: "parse", pwd: "password", roles: [ "readWrite", "dbAdmin" ] })
データ移行プロセスを開始する
ブラウザウィンドウで、Parseにログインし、アプリの設定を開きます。 一般の下で、移行ボタンを見つけてクリックします。
MongoDB接続文字列の入力を求められます。 次の形式を使用します。
mongodb://parse:password@your_domain_name:27017/database_name?ssl=true
たとえば、ドメインexample.com
を使用していて、ユーザーparse
、パスワードfoo
、およびtodo
というデータベースを使用している場合、接続文字列は次のようになります。こんな風に見える:
mongodb://parse:foo@example.com:27017/todo?ssl=true
最後に?ssl=true
を忘れないでください。そうしないと、接続が失敗します。 次のように、接続文字列をダイアログに入力します。
[移行の開始]をクリックします。 Parseでホストされているデータベースのスナップショットをサーバーにコピーし、スナップショットが作成されてから新しいデータを同期するための進行状況ダイアログが表示されます。 このプロセスの期間は、転送されるデータの量によって異なり、かなりの量になる場合があります。
データ移行を確認する
完了すると、移行プロセスは検証ステップに入ります。 まだ移行を完了しないでください。 まず、データが実際に転送されたことを確認し、ParseServerのローカルインスタンスをテストする必要があります。
mongo
シェルに戻り、ローカルデータベースを調べます。 database_name にアクセスし、そこに含まれるコレクションを調べることから始めます。
- use database_name
- show collections
Sample Output for Todo AppTodo
_Index
_SCHEMA
_Session
_User
_dummy
system.indexes
.find()
メソッドを使用して、特定のコレクションの内容を調べることができます。
- db.ApplicationName.find()
Sample Output for Todo App> db.Todo.find()
{ "_id" : "hhbrhmBrs0", "order" : NumberLong(1), "_p_user" : "_User$dceklyR50A", "done" : false, "_acl" : { "dceklyR50A" : { "r" : true, "w" : true } }, "_rperm" : [ "dceklyR50A" ], "content" : "Migrate this app to my own server.", "_updated_at" : ISODate("2016-02-08T20:44:26.157Z"), "_wperm" : [ "dceklyR50A" ], "_created_at" : ISODate("2016-02-08T20:44:26.157Z") }
特定の出力は異なりますが、アプリのデータが表示されるはずです。 満足したら、mongo
を終了し、シェルに戻ります。
- exit
ステップ3–ParseServerとPM2をインストールして構成する
MongoDBのアプリデータを使用して、Parse Server自体のインストール、およびシステムの他の部分との統合に進むことができます。 Parse Serverに専用ユーザーを割り当て、 PM2 というユーティリティを使用して構成し、常に実行されていることを確認します。
ParseServerとPM2をグローバルにインストールする
npm
を使用して、parse-server
ユーティリティ、pm2
プロセスマネージャ、およびそれらの依存関係をグローバルにインストールします。
- sudo npm install -g parse-server pm2
専用の解析ユーザーとホームディレクトリを作成する
parse-server
をrootまたはsudo
ユーザーとして実行する代わりに、parseというシステムユーザーを作成します。
- sudo useradd --create-home --system parse
次に、parseのパスワードを設定します。
- sudo passwd parse
パスワードを2回入力するように求められます。
ここで、su
コマンドを使用して、parseユーザーになります。
- sudo su parse
parseのホームディレクトリに移動します。
- cd ~
クラウドコードファイルの作成または移行
クラウドコードディレクトリを作成します。
- mkdir -p ~/cloud
/home/parse/cloud/main.js
を編集します:
- nano ~/cloud/main.js
テストの目的で、以下を貼り付けることができます。
Parse.Cloud.define('hello', function(req, res) {
res.success('Hi');
});
または、解析ダッシュボードのアプリ設定のクラウドコードセクションからコピーして、アプリケーション用に定義されたクラウドコードを移行することもできます。
終了して保存します。
キーを取得して/home/parse/ecosystem.jsonに書き込みます
PM2 は、Node.js開発者に人気の、機能豊富なプロセスマネージャーです。 pm2
ユーティリティを使用して、parse-server
インスタンスを構成し、長期間実行し続けます。
アプリのキーのいくつかを取得する必要があります。 解析ダッシュボードで、をクリックしますアプリの設定に続くセキュリティとキー :
このうち、アプリケーションIDとマスターキーのみが必要です。 その他(クライアント、JavaScript、.NET、およびREST APIキー) は、古いクライアントビルドをサポートするために必要な場合がありますが、設定されている場合は、すべてのリクエストで必要になります。 他に信じる理由がない限り、アプリケーションIDとマスターキーだけを使用することから始める必要があります。
これらのキーを手に入れる準備ができたら、/home/parse/ecosystem.json
という名前の新しいファイルを編集します。
- nano ecosystem.json
以下を貼り付け、MongoDB接続文字列、アプリケーションID、マスターキーを反映するように構成値を変更します。
{
"apps" : [{
"name" : "parse-wrapper",
"script" : "/usr/bin/parse-server",
"watch" : true,
"merge_logs" : true,
"cwd" : "/home/parse",
"env": {
"PARSE_SERVER_CLOUD_CODE_MAIN": "/home/parse/cloud/main.js",
"PARSE_SERVER_DATABASE_URI": "mongodb://parse:password@your_domain_name:27017/database_name?ssl=true",
"PARSE_SERVER_APPLICATION_ID": "your_application_id",
"PARSE_SERVER_MASTER_KEY": "your_master_key",
}
}]
}
env
オブジェクトは、環境変数を設定するために使用されます。 追加のキーを構成する必要がある場合、parse-server
は次の変数も認識します。
PARSE_SERVER_COLLECTION_PREFIX
PARSE_SERVER_CLIENT_KEY
PARSE_SERVER_REST_API_KEY
PARSE_SERVER_DOTNET_KEY
PARSE_SERVER_JAVASCRIPT_KEY
PARSE_SERVER_DOTNET_KEY
PARSE_SERVER_FILE_KEY
PARSE_SERVER_FACEBOOK_APP_IDS
ecosystem.json
を終了して保存します。
次に、pm2
を使用してスクリプトを実行します。
- pm2 start ecosystem.json
Sample Output...
[PM2] Spawning PM2 daemon
[PM2] PM2 Successfully daemonized
[PM2] Process launched
┌───────────────┬────┬──────┬──────┬────────┬─────────┬────────┬─────────────┬──────────┐
│ App name │ id │ mode │ pid │ status │ restart │ uptime │ memory │ watching │
├───────────────┼────┼──────┼──────┼────────┼─────────┼────────┼─────────────┼──────────┤
│ parse-wrapper │ 0 │ fork │ 3499 │ online │ 0 │ 0s │ 13.680 MB │ enabled │
└───────────────┴────┴──────┴──────┴────────┴─────────┴────────┴─────────────┴──────────┘
Use `pm2 show <id|name>` to get more details about an app
次に、pm2
にこのプロセスリストを保存するように指示します。
- pm2 save
Sample Output[PM2] Dumping processes
parseユーザーに対して実行されているプロセスpm2
のリストは、/home/parse/.pm2
に保存されているはずです。
ここで、サーバーを再起動するたびに、ecosystem.json
で前に定義したparse-wrapper
プロセスが復元されていることを確認する必要があります。 幸い、pm2
は独自にスクリプトを生成してインストールできます。
通常のsudo
ユーザーに終了します。
- exit
pm2
に、Ubuntuの初期化スクリプトをインストールし、/home/parse
をホームディレクトリとして使用して、parseユーザーとして実行するように指示します。
- sudo pm2 startup ubuntu -u parse --hp /home/parse/
[PM2] Spawning PM2 daemon
[PM2] PM2 Successfully daemonized
[PM2] Generating system init script in /etc/init.d/pm2-init.sh
[PM2] Making script booting at startup...
[PM2] -ubuntu- Using the command:
su -c "chmod +x /etc/init.d/pm2-init.sh && update-rc.d pm2-init.sh defaults"
System start/stop links for /etc/init.d/pm2-init.sh already exist.
[PM2] Done.
ステップ4–Nginxをインストールして構成する
Nginx Webサーバーを使用してリバースプロキシからparse-server
を提供し、TLS/SSLを介してParseAPIを安全に提供できるようにします。
前提条件では、Let’s Encrypt証明書によって提供されるSSLを使用して、ドメイン名に応答するようにdefault
サーバーを設定します。 この構成ファイルをプロキシ情報で更新します。
nano
(または選択したエディター)で/etc/nginx/sites-enabled/default
を開きます。
- sudo nano /etc/nginx/sites-enabled/default
メインのserver
ブロック(すでにlocation /
ブロックが含まれている必要があります)内に、/parse/
URLのプロキシを処理する別のlocation
ブロックを追加します。
. . .
# Pass requests for /parse/ to Parse Server instance at localhost:1337
location /parse/ {
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-NginX-Proxy true;
proxy_pass http://localhost:1337/;
proxy_ssl_session_reuse off;
proxy_set_header Host $http_host;
proxy_redirect off;
}
エディタを終了し、ファイルを保存します。 Nginxを再起動して、変更を有効にします。
- sudo service nginx restart
Output * Restarting nginx nginx
...done.
ステップ5–解析サーバーをテストする
この段階では、次のものが必要です。
- Let’sEncryptが提供するTLS/SSL証明書
- Let’sEncrypt証明書で保護されたMongoDB
parse-server
は、ポート1337の parse ユーザーの下で実行され、アプリで期待されるキーで構成されていますpm2
parseユーザーの下でparse-server
プロセスを管理し、起動時にpm2
を再起動する起動スクリプトnginx
、Let’s Encrypt証明書で保護され、https://your_domain_name/parse
への接続をparse-server
インスタンスにプロキシするように構成されている
これで、curl
を使用して、読み取り、書き込み、およびクラウドコードの実行をテストできるようになります。
注:このセクションのcurl
コマンドは、テストまたは開発アプリで使用する場合は無害である必要があります。 本番アプリにデータを書き込むときは注意してください。
POSTを使用したデータの書き込み
curl
にいくつかの重要なオプションを指定する必要があります。
オプション | 説明 |
---|---|
-X POST |
リクエストタイプを設定します。それ以外の場合はデフォルトでGET になります |
-H "X-Parse-Application-Id: your_application_id" |
アプリケーションを識別するヘッダーをparse-server に送信します |
-H "Content-Type: application/json" |
parse-server にJSON形式のデータを期待することを知らせるヘッダーを送信します |
-d '{json_data} |
データ自体を送信します |
これらをすべてまとめると、次のようになります。
curl -X POST \
-H "X-Parse-Application-Id: your_application_id" \
-H "Content-Type: application/json" \
-d '{"score":1337,"playerName":"Sammy","cheatMode":false}' \
https://your_domain_name/parse/classes/GameScore
{"objectId":"YpxFdzox3u","createdAt":"2016-02-18T18:03:43.188Z"}
GETを使用したデータの読み取り
curl
はデフォルトでGETリクエストを送信し、データは提供しないため、サンプルデータを読み戻すには、アプリケーションIDを送信するだけで済みます。
- curl -H "X-Parse-Application-Id: your_application_id" https://your_domain_name/parse/classes/GameScore
{"results":[{"objectId":"BNGLzgF6KB","score":1337,"playerName":"Sammy","cheatMode":false,"updatedAt":"2016-02-17T20:53:59.947Z","createdAt":"2016-02-17T20:53:59.947Z"},{"objectId":"0l1yE3ivB6","score":1337,"playerName":"Sean Plott","cheatMode":false,"updatedAt":"2016-02-18T03:57:00.932Z","createdAt":"2016-02-18T03:57:00.932Z"},{"objectId":"aKgvFqDkXh","score":1337,"playerName":"Sean Plott","cheatMode":false,"updatedAt":"2016-02-18T04:44:01.275Z","createdAt":"2016-02-18T04:44:01.275Z"},{"objectId":"zCKTgKzCRH","score":1337,"playerName":"Sean Plott","cheatMode":false,"updatedAt":"2016-02-18T16:56:51.245Z","createdAt":"2016-02-18T16:56:51.245Z"},{"objectId":"YpxFdzox3u","score":1337,"playerName":"Sean Plott","cheatMode":false,"updatedAt":"2016-02-18T18:03:43.188Z","createdAt":"2016-02-18T18:03:43.188Z"}]}
サンプルクラウドコードの実行
https://your_domain_name/parse/functions/hello
への実際のデータがない単純なPOSTは、/home/parse/cloud/main.js
で定義されたhello()
関数を実行します。
curl -X POST \
-H "X-Parse-Application-Id: your_application_id" \
-H "Content-Type: application/json" \
-d '{}' \
https://your_domain_name/parse/functions/hello
{"result":"Hi"}
代わりに独自のカスタムクラウドコードを移行した場合は、main.js
の既知の関数でテストできます。
ステップ6–サーバーの解析と移行の完了のためにアプリを構成する
次のステップは、ParseServerAPIエンドポイントを使用するようにクライアントアプリケーション自体を変更することです。 ParseServerでのParseSDKの使用については、公式ドキュメントを参照してください。 プラットフォームに最新バージョンのSDKが必要になります。 上記のcurl
ベースのテストと同様に、サーバーのURLには次の文字列を使用します。
https://your_domain_name/parse
ブラウザの解析ダッシュボードと移行タブに戻ります。
Finalizeボタンをクリックします。
これで、アプリが移行されます。
結論と次のステップ
このガイドは、ParseがホストするアプリをDigitalOceanドロップレットなどの単一のUbuntuシステムにインストールされたParseServerに移行するための機能的な開始点を提供します。 ここで説明した構成は、適度なユーザーベースを持つトラフィックの少ないアプリに適しているはずです。 大規模なアプリをホストするには、APIエンドポイント間の冗長データストレージと負荷分散を提供するために複数のシステムが必要になる場合があります。 小さなプロジェクトでさえ、私たちが直接対処していないインフラストラクチャの考慮事項を伴う可能性があります。
トラブルシューティング時に、Parse Serverの公式ドキュメントを読み、プロジェクトの GitHubの問題を追跡することに加えて、次のトピックを調べることをお勧めします。