エンジニア、オールインも辞さない

スタートアップやってます。Web系、アプリ系の話題多し。好きなことはポーカー、ウイスキー、アウトドア。

Parse.com移行を終えてわかったこと

以前Parse.com移行に関してこのような記事を書きました。それからしばらく時間が経ちましたのでそれ以降にわかったことを書きます。

potcommitted.hatenablog.com

1.サーバ実行環境について

上記記事ではmLabとさくらVPSの構成を書きましたが、結果的にmLab、Herokuの構成になりました。Parse ServerをさくらVPSに設置したときよりもHerokuに設置したときの方が圧倒的に実行速度が早いです。体感的にはParse.comとほぼ変わりませんでした。Herokuのスペックをあげればさらなる高速化が期待できそうです。

 

2.Parse.comのDBマイグレーションツールを使ってもファイルは移行されない件について

これは大変な地雷なので、多くの方に影響するのではないでしょうか。データベース自体を外に移行しても、ファイル自体はParse.comにありますのでそのままではParse.com閉鎖とともにファイルは消えてしまいます。データベースの移行というもっともらしい文言なので、ファイルも一緒に移行されると思いがちですがそんなことはありません。ファイル自体はParseの管理するAWS S3に保存されており、データベースではその参照情報を保持しているだけです。ですので、ファイルの実態を別の場所に移行し、かつデータベースの参照を変更しないとParse.com閉鎖後はアクセスできなくなります。ファイルの移行に対応しているmBaasであればまるっと移行できるようですが、mLabのようにDBだけ移行した人は自力で対応する必要があるので注意が必要です。

 

なお、下記ツールを使えばファイルの移行が可能です。

github.com

ただしファイルを配列で保持している場合はこのツールで移行できないという致命的な欠点があるので、自分で移行スクリプトを書くなりそれなりに頑張る必要があります。また、Parse.comに接続しているクライアントからは、新環境のファイルへのアクセス権限がない(Parse.comはAWS S3などファイルサーバへのアクセスキーを知らない)ので、ファイルを参照できない点にも注意が必要です。ですので、完全にサーバを新環境に移行したあとにファイルの移行を行った方がよいでしょう。

 

3.クライアントプッシュが動かない件について

セキュリティの事情により、クライアント間のプッシュが廃止されました。これは地味に面倒なことでして、それに変わる仕組みを用意する必要がでてきました。一般的にはCloud Codeを使えば解決すると思いますが、Herokuにようにプッシュ自体がうまくいかない環境もあるので(2017.01.26現在)、私の場合別にプッシュサーバを立てることにしました。

 

仕組みとしてはプッシュの送り元と送り先、そして送信ステータスを管理するクラスを用意し、それをバッチで検索、サーバ側でプッシュを行うというものです。メルカリ社のオープンソースでgaurunという優れたプロダクトがありまして、それを使うと簡単にプッシュ配信ができるようになるのでおすすめです。Goで書かれていて高速に動作します。

github.com

 

4.サーバからのメール送信ができない件について

Parse Serverを外だしした場合(外部のmBaasを使っている場合は除く)、パスワードリマインダなどサーバからのメールの送信ができなくなります。その場合、Mailgunを使用することで対応可能です。

www.mailgun.com

 

具体的な方法はこちらに記載されているので割愛しますが、Parse Serverの設定にMailgunの設定を加えて起動すれば動きます。

stackoverflow.com

総括

自前での運用は大変!

そういえば最近MovableType(ムーバブルタイプ)って聞きませんね。WordPressが強すぎる。

2000年代前半、まだ私がホームページというものを運営していた時代に栄華を誇っていたCMS(コンテンツマネジメントシステム)であるMovableTypeですが、最近見る影もなくなってしまいましたね。

www.sixapart.jp

当時はプロバイダ付属のレンタルサーバにHTMLを手動で転送して日記見たいのを書くような運用が流行っていた時代、MovableTypeの登場はまさに衝撃的でした。今でいうブログという形態を一般化したのにも一役買っています。当時はweblogとも言われていましたよね。今までbloggerだとか今でいうはてなブログ的なプラットフォームはありましたが、MovableTypeのように自分のサーバにソフトウェアを配置し、データを自前で持つという体験は相当に新しかった。デザインを改修するためにCSSを勉強したり、PHPを勉強したり当時はいろいろ楽しかったですね。

 

私が大学に入学しサイト運営よりの飲み会と麻雀を優先させた日々のあと、気づけはMovableTypeはいなくなりWordPressの一強になっていました。いつの間に潮目が変わったのかもわからないうちにWordPress一色です。MovableTypeで構築された私のサイトはDBが崩壊しもはやメンテナンスのしようもない状態へ。

 

やはりネットの世界は各ジャンルの一強だけが生き残ると強く思う次第です。MovableTypeシックスアパート社のもと、ライセンスフィーをベースにしたビジネスを進める一方で、WordPressオープンソースで全力の機能改善に励む。ブロードバンド化が加速し、プロダクトのブラッシュアップに集合知の力が働くようになった現在、ちょっとした事業思想の違いでこうも明暗が分かれるのだなと。

 

最近、WordPressをインストールする機会があり、あるVPSサーバにインストールしてみたのですがさすがの安定感ですね。インストールは楽勝、使い勝手も良好。プラグインも充実。良い時代になったものですね。なんなら大手のブログサービス提供者のサービスよりも使いやすいくらいです。

 

 

食べログのネット予約機能がかなり使える。電話しなくていいのはすごい良い。

飲み会やら会食やらで店を予約したことがある人はよくお分かりかと思うのですが、人数と予算を元に店を探して、店の空いている時間を待って電話して、こっちの電話番号を伝えてなど、大変ストレスフルなフローを取ることが多いですよね。特に日中オフィスで仕事をしている方々からすると、電話のために席を立って、店の予約をして、とかなりの苦痛を強いられることになります。そして電話したらしたでその時間は予約が埋まっていますだの、様々なトラップが仕掛けられているわけであります。予約する方も面倒だし、きっと夕方の忙しいときに電話対応をせざるをえないお店の人の苦痛も計り知れないと思うのです。

 

私はお酒を飲むのが好きなので、会社員時代の新人の頃からこういったフローを繰り返してきたわけですが、どうやら知らぬ間に食べログがネットでの予約が大変便利になっている様子。試しに使ってみたところ、なんと2クリックで店の予約ができてしまうのですね。これには大変な驚きを感じぜざるをえません。

 

 

f:id:splitaces:20160818152400p:plain

行きたい店を見つけて、日時と時間、そして人数を入力し「空席を確認・ネット予約する」ボタンを押すだけ。その後、電話番号など必要情報を入力する必要はありますが、なんというシンプルフローでしょうか。今まで電話して予約していたのがバカらしくなります。

 

最近ぺこったーを使って、予約の代行をよくしてもらっていたのですけど結局のところ電話でお店に電話するのが面倒だったから利用していた感があるんですよね。食べログでこんなに気軽に予約ができてしまうとなると、ぺこったーとしてはレコメンドの精度を上げるなり、予約のフローをより簡便化するなど差別化を図っていく必要がありそう。応援しています。

 

そしてとりあえずぐるなびはもうちょっと頑張ってほしい。ネット予約できると豪語しているものの、3営業日以降じゃないとだめとか飲食店のネット予約はやりにくい、というイメージを作った功罪は大きいですよ。予約したい店を見に行っても3営業日先じゃないとだめとか、折り返し電話が来るとか、面倒なんですよね。

f:id:splitaces:20160818153544p:plain

 

だからこそ食べログのイケてる感がありますよね。金曜日の日中に急に予約が必要になっても安心です。これは飲み会幹事としてはかなりの朗報なんじゃないでしょうか。

WebサーバにSSL証明書をインストールする方法(Apacheを使っている人向け)

近年WebサイトのHTTPS対応が話題になっています。Googleが公式にHTTPS対応サイトのインデックス順位を上げることを表明したことは記憶に新しいです。

www.seohacks.net

またAppleも2017年1月以降、iOSアプリのwebviewでwebサイトに接続する場合、HTTPSを使うことが絶対条件になると語っていることから、もはやこの流れには抗えようもありません。

jp.techcrunch.com

端的に言うと、HTTPSに未対応のサイトは今後順次淘汰されていく流れである、ということでしょう。これはWebサイトを運営している諸兄においては対応しないわけにはいかない状況だということです。

 

だからといって、そんな簡単にHTTPS対応できるのかといえばそんなことはありません。SSL証明書の設置代行が商売になってしまうくらいですからね。日頃からサーバの構築を行っている人はともかくとして、独自ドメインを使ってなんらかのサイトを運営しているような一般的な方にとってはまあまあハードルが高いものと思います。

 

というわけで、今回は私が実際に行ったHTTPS対応について手順を記載していきますので、お困りの方はどうか参考にしてください。なお私は下記条件で構築を行いましたのでそれに近い環境の方を対象としています。ご了承ください。

*HTTPS対応とは、WebサーバにSSL証明書をインストールしhttps://aaa.example.comようなURLにアクセスできるようにする一連の作業を指します。

 

対象の環境について

さくらVPSサーバ

 - Apache2.2

 - CentOS6.6

 

SSL証明書について

証明書はどのように機能し、どういう効果があるのかについては下記が詳しいです。

SSL サーバー証明書の基礎知識|サイバートラスト

 

また証明書の代理店は色々あるのですが、個人的には下記がおすすめです。とにかく値段が安いのと、担当の方のレスポンスが早いのがよいです。

www.slogical.co.jp

 

手順

では早速設定を行っていきましょう。

まずSSL証明書をインストールするサーバにログインして、適当なパスに移動してください。特にこだわりがなければ、httpdのパスで良いのではないのでしょうか。今回は下記を使います。

 

#証明書を配置するパスに移動します

cd /etc/httpd/conf

 

#秘密鍵を作成します。この時パスワードが要求されるので適当に入力します。あとで使いますので忘れないように。

*keyname.keyは任意の名前に置き換えて問題ありません

openssl genrsa -des3 2048 > keyname.key

 

#パスワード付き秘密鍵も作成しておきます

* keyname.withpass.keyは任意の名前に置き換えて問題ありません

openssl rsa < keyname.key > keyname.withpass.key

 

#CSRを作成します

CSRとは、「Certificate Signing Request」 のことで認証局に対し、SSLサーバ証明書への署名を申請する内容を指します

*csrname.csrは任意の名前に置き換えて問題ありません

openssl req -new -key keyname.key -out csrname.csr

この時色々必要な情報を問われるので適宜入力します。

Enter pass phrase for keyname.key: // 最初に入力したパスワードを入力します
You are about to be asked to enter information that will be incorporated
into your certificate request. // 組織の情報を入力してください的なことを言っています
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter '.', the field will be left blank.
-----

*下記は入力例です
Country Name (2 letter code) [XX]: JP
State or Province Name (full name) : Tokyo // 適宜変更してよいでしょう
Locality Name (eg, city) [Default City]: Marunouchi // 適宜変更してよいでしょう
Organization Name (eg, company) [Default Company Ltd]:My Company Name // 適宜組織名を入れてください
Organizational Unit Name (eg, section)
:My Section Name // 適宜担当部署名を入れてください。空でもおそらく大丈夫です
Common Name (eg, your name or your server's hostname) :yourdomainname.jp // *重要*httpsにしたいドメイン名を入力します。ここで入力を誤ると全てが台無しになるので注意してください。
Email Address
:info@yourdomainname.jp // 適宜メールアドレスを入力します

Please enter the following 'extra' attributes
to be sent with your certificate request
A challenge password : // 何も入力せずEnterで問題ありません
An optional company name
: // 何も入力せずEnterで問題ありません

 

#CSRの中身をcatし、コピーします

この内容を証明書の代理店に提出することで、証明書ファイルが発行されます。

cat csrname.csr

中身はこのようになっているので、BEGINからENDまで全てをコピーし、求められた方法に従って提出してください。

*下記内容は適当なのでご自分のCSRをご使用ください

-----BEGIN CERTIFICATE REQUEST-----
MIIC5jCCAc4CAQAwgaAxCzAJBgNVBAYTAkpQMQ4wDAYDVQQIDAVUb2t5bzESMBAG
A1UEBwdsawgdsJU2hpbmFnYXdhMRUwEwYDVQQKDAxISURFT1VUIENMVUIxFTATBg
DEhJREVPVVQgQ0xVQjEaMBgGA1UEAwwRbWcuaGlkZW91dGNsdWIuanAxIzAhBgkq
(中略)
XADXXrMm5kCbPgdsBZXhecHkjgGrflJOzUkugk9TECu1BelsePnEpFTKeOcB4kQE
ym3N70SsaZyXBiFyNrfVUo8BgPbhbsvJiS6Kdadsap3CTr3ABYsVPlxEqo7KOXwf
zv45FQSOS9MyuGsPdsgjo;uD917Aoi7wfhhBHpFoMCEqm8QDNW+DOO71I3H/DH2Q
TL5JpEedNm+trroMrqNrb17r0plHS7T7eho=
-----END CERTIFICATE REQUEST-----

 

決済完了後、しばらくすると証明書ファイルが通知されます。上記Geo Trustの場合はメールにて証明書が送付されてきます。下記のような文字列が送られてきますのでそれをコピーします。

-----BEGIN CERTIFICATE-----
MIIGVjCCBT6gAwIBAgIQaGETvf5acG7rgihcHOsQwzANBgkqhkiG9w0BAQsFADBC
MQswCQYDVQQGEwJVUzEWMBQGA1UEChMNR2VvVHJ1c3QgSW5jLjE
(中略)
Y3Tc5aIJgjuuBLoahsPGM5w3K/vHV5WMAHzFwCwp5U1fp5zR3VXlN1HZ
-----END CERTIFICATE-----

 

上記でコピーした内容を下記に保存し証明書ファイルを作ります

*ファイル名は任意です。

vi crtname.crt

 

また必要に応じて別途メールにて通知される中間証明書ファイルもコピーしてサーバに配置します。(SHA2(クロスルート)という名前のものを使います)

*ファイル名は任意です。

vi cstname.cst

 

これにて必要なファイルが出揃いました。最後にこれらをApacheにロードさせて完了となります。下記パスにvhosts.confというファイルがあるので、そこを編集します。

#pwd
/etc/httpd/conf.d
#ls -ld vhost.conf
-rw-r--r-- 1 root root 2629  8月 17 15:24 2016 vhost.conf

#vi vhost.conf

 

特定のドメインにアクセスしたときにhttpsでロードさせるために、443ポートに対してこのような設定を行います。下記を追加後apacheを再起動すると証明書が有効になります。

NameVirtualHost *:443
<VirtualHost *:443>
    DocumentRoot /var/www/html/yourdomainname.jp
    ServerName yourdomainname.jp:443
    SSLEngine on
    SSLProtocol all -SSLv2
    SSLCipherSuite ALL:!ADH:!EXPORT:!SSLv2:RC4+RSA:+HIGH:+MEDIUM:+LOW
    SSLCertificateFile /etc/httpd/conf/csrname.crt
    SSLCertificateChainFile /etc/httpd/conf/cstname.cst
    SSLCertificateKeyFile /etc/httpd/conf/keyname.withpass.key
    SSLOptions +StdEnvVars
    SetEnvIf User-Agent ".*MSIE.*" nokeepalive ssl-unclean-shutdown downgrade-1.0 force-response-1.0
</VirtualHost>

 

ブラウザでアクセスしたときにアドレスバーに鍵マークがかかっていればうまく反映されたということになります。

StoryBoardのNavigationBarが非表示になってしまったときに対処方法

StoryBoard上のNavigationBarが突然表示されなくなって困ったことはありませんでしょうか?既にNavigation Controllerを使用しているのにもかかわらずなぜか表示されないというのは萎えますよね。こういう状態です。

Navigation Controllerの支配下にあるはずなのにバーが表示されない図

f:id:splitaces:20160623192935p:plain

 

これが本来の正しい状態

f:id:splitaces:20160623193121p:plain

 

Xcodeのバグなのかわかりませんが、再起動してもCleanしても一度表示されなくなってしまったNavigation Barは表示されません。そういうときは次の操作で表示を復活させることができます。

 

XcodeのStoryBoard画面右の「Attributes inspector」を開き「Simulated Metrics」の「Top Bar」をデフォルトの"Inferred"からNone以外、例えば"Translucent Navigation Bar"を選択してみてください。

f:id:splitaces:20160623193926p:plain

 

f:id:splitaces:20160623193935p:plain

 

そうするといかがでしょう。いままで非表示だったNavigation Barの表示が復活するとおもいます。どうぞお試しください。

【Parse移行手順】DB:mLab, Web:さくらVPSの構成で移行を行いました

以前Parseの移行先はどこがいいのかという記事を書きました。

potcommitted.hatenablog.com

色々試行錯誤してきたのですが、一通り対応が完了したので手順を公開していこうと思います。なお、私はDBにmLabを使い、WebサーバはさくらVPSで構築という構成を採用しました。

 

このような方におすすめしています:

- Parseを使ったアプリの運営をしているが、具体的な移行方法がわからず困っている人

- サーバサイドの構築もそこそこできる人

- 他のBaaSに移行するリスクを感じている、もしくはこれを機に自前で運用しようと思っている人

 

目次:

- Parse移行についての概要

- DBの移行

- Parse Serverの移行

- SDKの更新

- Parse Dashboardの移行

- 最後に

 

Parse移行についての概要

まず前提として、Parseのサービス自体は2017年1月をもって終了します。いままでParseに依存してきた人はこのタイムリミットまでにデータを他のサービスに移行するか自前で環境を構築する必要が出てきます。なお、公式からは下記のようなスケジュールが推奨されていますが、基本的にこのくらい余裕をもって対応することをおすすめしています。理由としてはParse Serverの存在があります。今までSDK経由でアプリからParse ServerにアクセスしてDBからデータを取得していましたが、このParse Serverが2017/01をもって使えなくなる関係で、この時までにユーザサイドのアプリの接続先が新しいものになっていないとアプリが存続不可能になる可能性があるためです。

f:id:splitaces:20160617110527p:plain

Parse | Migration Guide

 

簡単な概要図を作りました。イメージとしてはこんな感じです。

 

f:id:splitaces:20160617111331p:plain

 

では具体的な手順を見ていきましょう。

 

DBの移行

今回の作業で一番重要かつ慎重にやらないとならないのはここではないでしょうか。今までのアプリ運営で得た様々な重要データが含まれるわけでここを失敗すると大変なことになります。ガイドではmongoDBのインフラプロバイダであるmLabObjectRocketsへの移行が推奨されています。もちろん自前でmongoDBを構築しても構いませんが、今回私はmLabを使うことにしました。理由としてはリスクとコストのバランスでしょうか。DBは自分で構築することもできますが、なかなか運用コストが高くかつトラブルがそこそこ起こりうるので、外のインフラに頼ることにしました。mongoDBに詳しいエンジニアがいるチーム以外は外出しをおすすめします。

 

では早速mLabにアクセスしてサインアップしましょう。既にアカウントがある人はログインして画面右上にCreate newをクリックし、DBを作っていきます。(私のアカウントでは既にdevと本番のDBがあるので画面のみためが多少違うと思います。)

f:id:splitaces:20160617113510p:plain

 

Single-nodeのSandboxを選び、適当な名前をDBにつけて「create new MongoDB deployment」をクリックします。Cloud Providerはどこでも構いません。私はAWSにしました。もし本番で運用したい場合はもっとリッチなプランに変更してください。sharedのクラスタで月間$15くらいですね。この価格でMongoDBのプロフェッショナルを雇ったり自分で運用しなくてもよいのですから大変な安上がりだと思います。

f:id:splitaces:20160617113946p:plain

f:id:splitaces:20160617114000p:plain

 

続いて、ログイン後トップページから先ほど作成したDBをクリックし、接続に使うユーザを作成していきます。画面右の「Add database user」をクリックし使いたいユーザ名とパスワードを設定します。そして画面中段の接続先情報を作っておきます。「mongodb://<dbuser>:<dbpassword>@ds00000.mlab.com:12345/{dbname}」というやつです。基本コピペして、ユーザ名、パスワードを自分のやつに置き換えれば問題ありません。

f:id:splitaces:20160617114437p:plain

 

mLabでの作業は一旦ここで完了です。続いてはParseダッシュボードにアクセスしてください。対象のプロジェクトにアクセスし、左メニューの「App Settings > General」へいき、画面中段の「App Management」から「Migrate to external database」という項目を探し、「Migrate」というボタンを押します。(新しいダッシュボードからしかこの操作はできないものと思いますのでご注意ください。)

f:id:splitaces:20160617115716p:plain

 

このようなダイアログが出ると思うので、先ほどmLabで作成したDBの情報を入力し、「Begin to migraion」をクリックします。

mongodb://<dbuser>:<dbpassword>@ds00000.mlab.com:12345/{dbname}

という感じのものですね。

f:id:splitaces:20160617115843p:plain

 

この時「We strongly suggest you enable SSL on your database and use the URL option 'ssl=true'.」という警告が出るかもしれませんが「Migrate anyway」を押すと続行されます。気になる方はキャンセルした上でSSLの対応を行ってください。

 

この作業後自動でデータの移行作業が行われます。Copy SnapshotとSyncが完了すればデータの移行は完了しています。このステータスの状態で再度mLabにアクセスし、今までParseに保存されていたデータが正しくmLabに移行されていることと、Parseと接続されているアプリでデータの登録、削除などを行い、正しくデータが反映されていることを確認してください。データの確認ができましたら「Finalize」をクリックし、移行を完了してください。

f:id:splitaces:20160617120731p:plain

 

一度移行するともう差し戻しできないよ、という警告メッセージがでますが十分に確認したのちに「Okey」を押して完了します。

f:id:splitaces:20160617131222p:plain

 

無事に完了しますとCongratulations!とのメッセージが出ます。お疲れさまでした。

なお、この時点ではアプリで新規に作成されたデータは、Parse内のParse Serverを経由して、先ほど構築したmLabに格納されています。この作業を通じて、DBへの接続先が変更されたということです。

f:id:splitaces:20160617131122p:plain

 

Parse Serverの移行

続いてParse Serverの構築を行います。公式のガイドではHerokuを使うことが推奨されていますが、今回は自前のサーバを使うことにします。もちろんHerokuが使い易い人は使っていただいて問題ありません。私はさくらのVPSさくらのクラウドで動作確認済みなので、それに準じた環境であればどこでも構いません。

 

まずParse Serverはnode.js上で稼働しますのでまだnode.jsが入っていないという方は適宜インストールしてください。実行ユーザは任意のもので大丈夫です。なお、必要に応じて最初にnvmのインストールを行います。

 

# nvmのインストール
curl -o- https://raw.githubusercontent.com/creationix/nvm/v0.25.4/install.sh | bash 

# bash_profileの設定 
vi .bash_profile 
/////////////////////// 
# nvm設定 
 -s ~/.nvm/nvm.sh  && . ~/.nvm/nvm.sh 
nvm use default npm_dir=${NVM_PATH}_modules 
export NODE_PATH=$npm_dir
/////////////////////// 
# バージョンの確認 
nvm --version 
#設定の反映 source ~/.bash_profile
#(必要ならば)使えるバージョンの一覧 nvm ls-remote #最新版をインストール nvm install 6.2.0 #実行
nvm use v6.2.0 Now using node v6.2.0 (npm v3.8.9) # bash_profileの更新 vi .bash_profile /////////////////////// # nvm設定 -s ~/.nvm/nvm.sh && . ~/.nvm/nvm.sh nvm use v6.2.0 // これに変更 npm_dir=${NVM_PATH}_modules export NODE_PATH=$npm_dir ///////////////////////

 

Parse Serverの稼働できるバージョンがあったはずなので、node.jsは新しい安定板にしておくことをおすすめします。続いてParse Serverをインストールします。

#インストール
npm install -g parse-server
 
#接続先設定
#起動パタメータにこの辺りの情報を含むことはできますが、json形式の設定ファイルにしておくと便利です。各種key情報やpushの情報も含むことができます。 vi config.json { { "appId”:”appid”, "masterKey”:”masterkey”, "clientKey": "masterKey", "restAPIKey": "restAPIKey", "databaseURI":"mongodb://username:password@ds01111.mlab.com:35674/dbname”, "push": { "android": { "senderId":"senderId", "apiKey":"apiKey" }, "ios": { "pfx":"/home/xxxxx/parse/APNS/yourappname.p12", "bundleId":"jp.example”, "production":true } } } #起動方法 parse-server config.json #リモートデータの取得テスト curl -X GET \ -H "X-Parse-Application-Id: yourappid” \ http://localhost:1337/parse/classes/Test/aabbccdd #サーバに外からつなぐ場合はポートの開放が必要 cat /etc/sysconfig/iptables #1337ポートを開けるため、下記を追加。ポート番号は好きに変更してください。 -A RH-Firewall-1-INPUT -m state --state NEW -m tcp -p tcp --dport 1337 -j ACCEPT #再起動 /etc/init.d/iptables restart #CentOS7の場合はiptablesが使えないので下記のようにしポートを解放します firewall-cmd --add-port=1337/tcp --zone=public --permanent success firewall-cmd --reload success #外から(他のサーバやローカルPCから)つなぐ場合 curl -X GET \ -H "X-Parse-Application-Id: appid” \ http://yourhostname.co.jp:1337/parse/classes/Test/aabbccdd

これでParse Serverの構築が完了しました。ここに対して処理を行うことで、最初に構築したDBのデータの操作を行うことが可能になってきます。

 

SDKの更新

DBとParse Serverの構築が終わりましたのでアプリ側のSDKの更新を行っていきます。手順はこちらに記載されている通りです。

github.com

Swiftの場合はこんな感じですね。今までparse.comへ向いていたコネクションを先ほど構築した自前のParse Serverに置き換えます。

let configuration = ParseClientConfiguration {
    $0.applicationId = "YOUR_APP_ID"
    $0.clientKey = ""
    $0.server = "http://localhost:1337/parse"
}
Parse.initializeWithConfiguration(configuration)

なお、このような記法は最新のSDKにアップデートしないと使えない場合がありますのでその場合は下記より適切なバージョンをDLしアプリに組み込んでからお試しください。

parse.com

最後に接続先を変更したアプリをApp Storeに申請をあげて完了です。

 

Parse Dashboardの移行

最後にダッシュボードを移行します。Parseにログインしたあとにデータをみるときに使うあの画面です。早速設定していきましょう。

 

#parse dashboardのインストール
npm install -g parse-dashboard
 
#設定ファイル
#userとpassを設定することでダッシュボードアクセス時にBasic認証を有効にすることができます。 #vi parse-dashboard-config.json { "apps": [ { "serverURL": "http://yourhostname.jp:1337/parse", "appId": “appId”, "masterKey": “masterKey”, "appName": “appName”, "production": true } ], "users": [ { "user”:”user1”, "pass”:”pass1” } ] } #設定がうまくできない場合はparse-dashboard以下のパスに配置する必要があります /home/youruser/.nvm/versions/node/v6.2.0/lib/node_modules/parse-dashboard/Parse-Dashboard/parse-dashboard-config.json #起動 parse-dashboard /home/youruser/.nvm/versions/node/v6.2.0/lib/node_modules/parse-dashboard/Parse-Dashboard/parse-dashboard-config.json --allowInsecureHTTP true & #備考 「—allowInsecureHTTP true」 を引数につけることでhttpでアクセスできるようになります。 #必要に応じて4040ポートを開放 sudo vi /etc/sysconfig/iptables #追加 -A RH-Firewall-1-INPUT -m state --state NEW -m tcp -p tcp --dport 4040 -j ACCEPT #再起動 /etc/init.d/iptables restart

これでダッシュボードの構築が完了しました。無事にいつもような画面が表示されていれば問題ありません。


最後に

これで一通りの移行作業は完了です。断片的に見ると色々面倒なことが多いのですが、全体像を掴みつつ行うと難易度は下がりますね。とはいえ、サーバサイドのナレッジがないからParseを使っていましたという人からするとなかなか厄介なことに変わりありません。移行ドキュメントも全部英語ですし、そこそこハードルは高いはず。そう考えるとこの移行作業を機にサービスクローズしてしまうアプリもあるんだろうなと思った次第です。必要な方のお役に立てればうれしいです。

 

なお、現時点で私が気になっていることをこちらに記載しておきます。

1.dev版のAPNS証明書でpushが飛ばない問題

pushを行うと下記のようなエラーが表示され正しく配信が行われません。

>ERR! parse-server-push-adapter APNS cannot find vaild connection for 96f7a07515e4dda535c291b673060e80b1f196c35797e28df352d96bf593632c

 

本件海外でも話題になっています。

github.com

原因は不明ですがなんらかのサーバ環境依存の可能性はあります。Herokuでは問題なく飛んだなど情報がありましたらコメントいただけると困っている人が助かります。なお私の場合、本番の証明書をロードさせたところdev環境でもpush配信を行うことができました。

 

2.自前のParse Serverを使用したアプリのデータロードが遅い問題

これは致命的な問題かと思います。parse.comのサーバでは特にストレスなくロードされていたデータが、移行後のParse Serverを使ったバージョンでは異常にロードに時間がかかるようになりました。どこに問題があるのかわからなかったので下記検証を行いましたがいずれにせよparse.com使用時は早く、移行後のParse Serverでは遅いということには変わりありませんでした。

 

-DBのスペックの比較。sandboxとそうでない環境へ接続先を変更しても特に変化なし

-サーバスペックの比較。VPSサーバ、クラウドサーバ(コア数、メモリ数)など5パターンくらいで比較したところ、ハイスペックの方が極めて微妙にロード時間が短縮されたがほぼ影響なし。(下は1GBメモリ、1coreCPU、上は16GBメモリ、4coreCPU)

 

よって、現時点のオープンソース版のParse Serverに問題があるのではないか?というのが濃厚です。海外でも話題になっているのでこれは定期的にウォッチしておく必要がありそうです。

github.com

これだけロードに時間がかかってしまうとユーザビリティに多大な影響を与えてしまうので、Parse Serverのパフォーマンスが向上するまではparse.comサイドのサーバを接続先に使い、どこかのタイミングで切り替えるという運用が正しいのかもしれません。

 

2017/01/26追記

potcommitted.hatenablog.com

ParseのデータをPHPスクリプトを使用してjson形式で保存する

Parseのデータの管理って皆さんどうやっているのでしょうか?稼働中のシステムのDBのデータは大変重要なデータを含みますので、常にバックアップを取っておきたいところですよね。バックアップなしのシステム運用は商用サービスをやっている限りはユーザ影響が出るという意味で禁忌かと思います。

さてParseでは親切なことにダッシュボードからデータのexport機能が提供されております。

f:id:splitaces:20160526164716p:plain

しかし悲しいことに、完全にマニュアル操作が要求されます。自動的にレプリケーションしてくれるほど優しい設計にはなっていません。毎日毎日手作業でポチポチバックアップできる人なんてそういないわけですから、おとなしくシステムで処理する方法を検討していきましょう。

今回使うのはParseのphp-sdkです。githubにおいてあります。これを使うとPHPからParse上のデータへアクセスすることができます。

githubに詳しいことが書いてあるので大きな流れだけ書くと、

1.(入ってなかったら)composerをインストールします
2.composer経由でparse-php-sdkをインストールします
3.使いたいシステムで自分のParseのApplicationId, REST API Key, Master Keyを設定します

という感じです。

個人的にcomposerは変な依存ができるのであんま好きではないのですが仕方ありません。コマンドラインからでもNetBeansからでもインストールできますので好きな方をお選びください。NetBeansからの方が簡単かな。

インストールが完了するとvendorディレクトリの下にparseディレクトリができて、その中にphp-sdkがあるという構成になっているはずです。

この状態でプロジェクト内にphpスクリプトを作成し、parseへ接続していきます。

<?php
date_default_timezone_set('Asia/Tokyo');
require 'vendor/autoload.php';

// データ取得数
$limitCount = 1000;
// skip
$skip = 0;

// key
$appId = ‘xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx’;  
$restKey = ‘yyyyyyyyyyyyyyyyyyyyyyyyyyyyyy’;  
$masterkey = ‘zzzzzzzzzzzzzzzzzzzzzzzzzzzzzz’;

 
// 情報を取得したいClass名
$className = "Note";

if ($className == "Installation") {
        $url = 'https://api.parse.com/1/installations';
    } else if ($className == "User") {
        $url = 'https://api.parse.com/1/users';
    } else {
        $url = 'https://api.parse.com/1/classes/' . $className;
    }
    $params = '?limit=' . $limitCount;
    $params .= '&skip=' . $skip;


    $headers = array(
        "X-Parse-Application-Id: $appId",
        "X-Parse-REST-API-Key: $restKey",
        "X-Parse-Master-Key:  $masterkey"
    );

    $handle = curl_init();
    curl_setopt($handle, CURLOPT_URL, $url);
    curl_setopt($handle, CURLOPT_HTTPHEADER, $headers);
    curl_setopt($handle, CURLOPT_SSL_VERIFYPEER, false);
    curl_setopt($handle, CURLOPT_RETURNTRANSFER, true);
    curl_setopt( $handle, CURLOPT_URL, $url . $params );

    $data = curl_exec($handle);
    curl_close($handle);

    $results = json_decode($data);

 

このphpスクリプトを実行すると、ソース内で指定したクラスのデータを引っこ抜いてこられます。データ形式jsonなので別のmongoDBに突っ込んだりするのにも便利かと思います。なお、クラス名を引数に指定しつつ全件を自動的にすべて持ってくるようなことも可能です。Parseでは一度のリクエストでは1000件しか持ってこられないので、ちょっと工夫が必要です。そうしたちょっとリッチなスクリプトに興味があるがよくわからんという方のために全文を下記にて公開していますので欲しい方はどうぞ。(ソースコードって有料でもニーズがあるかどうかのトライアルも兼ねてます。)

note.mu