Araoの技術ブログ

見習いエンジニアのAraoが、学んだことなどを書いたりするブログです。

Ruby on Railsの環境の確認と設定の方法

Ruby on Railsの環境の確認方法と設定方法を知ったので、ほぼ自分用のメモとしてブログ記事にしておきます。
Rubyの経験も浅い僕ですが、最近はRailsを触っております。当然Railsに関しては素人なので、まだまだわからないことも多いのですが、APIを実装し、サーバを起動して、curlコマンドでAPIへのアクセスを再現してテストをする、というところをなんとか頑張っている最中です。
勉強のために一冊本を買ったので、実作業だけでなく、きちんと勉強も進めていきたいところです。

さて、本題に入ります。Railsの環境についてです。
自分が今実装を進めているRailsアプリケーションには、production、development、testの3種類の環境があります。
調べてみると、productionは本番環境、developmentが開発環境、testがテストを実行するとき用の環境、だそうです。
そこで、productionに本番で使用する定数を、developmentとtestに本番では使用しないテスト用の定数を、それぞれ設定しました。具体的には以下のような感じです。

config/settings/production.yml

hogehoge:
  fugafuga: 'http://production.com'

config/settings/development.yml, config/settings/test.yml

hogehoge:
  fugafuga: 'http://development.com'

これにて一件落着、と言いたいところですが、今自分がどの環境でAPIを動かしているのか確認したいですし、どの環境でAPIを動かすのか自分で設定したいと思うのが人間です。僕も人間なのでそうでした。
そこで、Railsの環境の確認方法と設定方法を調べてみました。

まず、環境の確認方法です。

参考:RailsGuides Railsアプリケーションを設定する

こちらによると、Railsが実行される環境を定義しているのはENV["RAILS_ENV"]だそうです。

$ bundle exec rails s

としてサーバを起動した場合、ソースコード中のputsなどはサーバのコンソールに表示されるため、ソースコード中に

puts ENV["RAILS_ENV"]

としてあげれば、サーバのコンソールにdevelopmentなどと表示されます。
もっとスマートな方法がありそうですが、とりあえず環境の確認方法でした。

次に、環境の設定方法です。

参考:RailsGuides Railsのコマンドラインツール

こちらによると、サーバを起動する際に、オプションを付けることで、環境の設定ができるようです。僕も試してみました。

$ bundle exec rails s -e test

このようにサーバを起動し、先ほどの方法で環境を確認すると、きちんとtest環境になっていることが確認できました。
また、何もつけないでサーバを起動すると、development環境になるそうです。

余談ですが、production環境でサーバを起動して、同様の方法で環境を確認しようとしても、エラーが出てしまいます。
原因となっている箇所とその理由はなんとなくわかりますが、まだ理解は不十分なので、これ以上深く掘り下げるのはやめておこうと思います。

以上、Ruby on Railsの環境の環境の確認方法と設定方法でした。

Let's Encryptで取得した証明書をHerokuに反映させてみた

Let's Encryptで取得したSSL証明書を、Herokuで公開しているアプリケーションに反映させた話です。
Let's Encryptで取得した証明書は90日後までには更新しないといけないようなので、次回更新時に手順がわからず途方に暮れないように、作業手順を記事にしてみます。
SSL証明書などの知識に乏しいため、説明が不十分な点などあるかと思いますが、ご了承ください。
なお、作業環境は基本的にMacのターミナルです。

今回対象としたのは、既にHerokuで公開されているアプリケーションです。個人のドメインが設定されており、my_app.herokuapp.comだけでなく、my_domainにアクセスすることでも、アプリケーションを利用できます。
ちなみにそのアプリケーションはSinatraを利用しています。関連情報を検索するとRuby on Railsがよくヒットしますが、やることはそこまで大きく変わらないと思うので、気にせず進めていきましょう。

今回の記事の大まかな流れを示します。
1. Let's Encryptのクライアントソフトウェア、Certbotを導入する
2. Let's EncryptでSSL証明書を取得する
3. 取得したSSL証明書を個人のドメインに反映させる
こんな感じです。それではさっそく1番から進めます。

まずは1番、Let's Encryptのクライアントソフトウェア、Certbotを導入する方法を説明します。

参考:Let's Encrypt 総合ポータル Let's Encrypt の使い方

僕はこちらを参考に進めました。
初めに、gitのインストールが必要になりますが、僕は既にインストールされていたため、それは飛ばします。
次に、git cloneしてCertbotクライアントをダウンロードします。gitを使ったことのある方にはおなじみですね。
ダウンロードしたら、cloneしたディレクトリに移動して、Certbotを実行できる環境が整っているかテストします。基本的には書いてある通りに進めればいいのですが、僕はこんな警告が出ました。

$ cd certbot/
$ ./certbot-auto

WARNING: Mac OS X support is very experimental at present...
if you would like to work on improving it, please ensure you have backups
and then run this script again with the --debug flag!

どうやらMac OS Xのサポートはとても実験的(?)なようです。それでも動作させたいなら、バックアップを確認して、--debugフラグをつけて再びこのスクリプトを実行するように言われています。
もちろん--debugをつけて再度実行します。

$ ./certbot-auto --debug

実行すると、Homebrewで自動的にいくつかのパッケージがインストールされていきます。途中、root権限が要求されるので、パスワードを入力してあげましょう。
パッケージのインストールが終わると、Certbotクライアントが起動して、TUIが表示されます。ここでは一旦NOを選択して、クライアントを終了します。
これでLet's Encryptのクライアントソフトウェア、Certbotの導入は完了です。

次に2番、Let's EncryptでSSL証明書を取得する方法を説明します。

参考:Let's encryptをHerokuにあるRailsアプリに適用する

僕はこちらを参考に進めました。
Let's Encryptでは、特定のURLへのアクセスに対して特定の値を返すことで認証を行い、証明書を発行してもらう仕組みのようです。
具体的には、

my_domain/.well-known/acme-challenge/REQUEST_KEY

というURLにアクセスしたら、

RESPONSE_KEY

という値を返せばいいということです。もちろん、REQUEST_KEYとRESPONSE_KEYは、Let's Encryptのコマンドを実行したときに取得できる値です。
さっそくやってみます。

まず、今回の対象はSinatraを利用しているアプリケーションなので、main.rbに以下のような記述を追加してあげます。

get "/.well-known/acme-challenge/:id" do
    ENV["LETSENCRYPT_RESPONSE"] if params[:id] == ENV["LETSENCRYPT_REQUEST"]
end

LETSENCRYPT_REQUESTとLETSENCRYPT_RESPONSEはHerokuの環境変数です。
記述を追加したら、デプロイを忘れないようにしましょう。

次に、Herokuの環境変数を設定するのですが、その前にHeroku Toolbeltという、Heroku用のコマンドラインツールなどを含んだアプリケーションをインストールする必要があります。
次のステップでも必要になるので、インストールしておきましょう。

Heroku Toolbelt

無事インストールが完了したら、環境変数をセットします。セットの前にHerokuにログインしておきます。メールアドレスとパスワードを入力するだけです。

$ heroku login
Enter your Heroku credentials.
Email: my_email
Password (typing will be hidden): 
Logged in as my_email
$ heroku config:set LETSENCRYPT_REQUEST=aaa -a my_app
$ heroku config:set LETSENCRYPT_RESPONSE=bbb -a my_app

環境変数をセットしたら、ちゃんと期待通りの動作をするか、確認しておきましょう。
今回の例だと、

my_domain/.well-known/acme-challenge/aaa

にアクセスして、

bbb

という値が返ってくれば、期待通りの動作をしていることになります。

さて、いよいよSSL証明書を取得します。Certbotのディレクトリに移動して、以下のコマンドを実行します。

$ cd certbot/
$ ./certbot-auto certonly --manual -d my_domain
Requesting root privileges to run certbot...
  /Users/USERNAME/.local/share/letsencrypt/bin/letsencrypt certonly --manual -d my_domain
Password:

root権限のパスワードを入力して表示された画面でYESを選択すると、以下のような指示が表示されます。

Make sure your web server displays the following content at
http://my_domain/.well-known/acme-challenge/REQUESTREQUESTREQUESTREQUESTREQUESTREQUESTR before continuing:

RESPONSERESPONSERESPONSERESPONSERESPONSERESPONSERESPONSERESPONSERESPONSERESPONSERESPONS

If you don't have HTTP server configured, you can run the following
command on the target server (as root):

mkdir -p /tmp/certbot/public_html/.well-known/acme-challenge
cd /tmp/certbot/public_html
printf "%s" RESPONSERESPONSERESPONSERESPONSERESPONSERESPONSERESPONSERESPONSERESPONSERESPONSERESPONS > .well-known/acme-challenge/REQUESTREQUESTREQUESTREQUESTREQUESTREQUESTR
# run only once per server:
$(command -v python2 || command -v python2.7 || command -v python2.6) -c \
"import BaseHTTPServer, SimpleHTTPServer; \
s = BaseHTTPServer.HTTPServer(('', 80), SimpleHTTPServer.SimpleHTTPRequestHandler); \
s.serve_forever()" 
Press ENTER to continue

ここで、新しいターミナルのウィンドウを開いて、そちらでHerokuの環境変数を設定し直します。

$ heroku config:set LETSENCRYPT_REQUEST=REQUESTREQUESTREQUESTREQUESTREQUESTREQUESTR -a my_app
$ heroku config:set LETSENCRYPT_RESPONSE=RESPONSERESPONSERESPONSERESPONSERESPONSERESPONSERESPONSERESPONSERESPONSERESPONSERESPONS -a my_app

環境変数の設定が完了したら、元のターミナルのウィンドウに戻って、Enterキーを押します。
認証が成功すると、こんな感じの情報が表示されます。

IMPORTANT NOTES:
 - Congratulations! Your certificate and chain have been saved at
   /etc/letsencrypt/live/my_domain/fullchain.pem.
   Your cert will expire on 2016-11-01. To obtain a new or tweaked
   version of this certificate in the future, simply run certbot-auto
   again. To non-interactively renew *all* of your certificates, run
   "certbot-auto renew"
 - If you like Certbot, please consider supporting our work by:

   Donating to ISRG / Let's Encrypt:   https://letsencrypt.org/donate
   Donating to EFF:                    https://eff.org/donate-le

この先必要になるのは、

  • crtファイル:/etc/letsencrypt/live/my_domain/fullchain.pem
  • keyファイル:/etc/letsencrypt/live/my_domain/privkey.pem

です。
確認してみましょう。

$ sudo ls /etc/letsencrypt/live/my_domain/
cert.pem        chain.pem    fullchain.pem    privkey.pem

これでSSL証明書の取得は完了です。

最後に3番、取得したSSL証明書を個人のドメインに反映させる方法を説明します。

参考:Heroku SSL (Beta) | Heroku Dev Center

基本的にはこちらの解説にしたがって進めていきます。
日本語の情報を調べてみると、月額20ドルかかるとかなんとか出てきたりしますが、Beta版のHeroku SSLを使うことで無料で(クレジットカードの登録などをすることなく)反映できました。

SSLを使用するには、フラグを有効にしてCLIプラグインをインストールする必要があるようなので、ますはそちらを行います。

$ heroku labs:enable http-sni -a my_app
Enabling http-sni for my_app... done
$ heroku plugins:install heroku-certs
Installing plugin heroku-certs... done

もしかしたら何かメッセージが出てくるかもしれません。
次に、いよいよ証明書を反映させます。

$ sudo heroku _certs:add /etc/letsencrypt/live/my_domain/fullchain.pem /etc/letsencrypt/live/my_domain/privkey.pem -a my_app

ここでもし、

Only one SNI endpoint is allowed per app (try sni:update instead)

や、

Must pass either --type with either 'endpoint' or 'sni'

というメッセージが出て失敗する場合は、先ほどのコマンドの代わりに、

$ sudo heroku _certs:update /etc/letsencrypt/live/my_domain/fullchain.pem /etc/letsencrypt/live/my_domain/privkey.pem -a my_app

を実行してみてください。
確認のため、my_appの入力が求められますので、入力します。 無事反映されたら、以下のコマンドで証明書の詳細を確認できます。

$ heroku _certs:info -a my_app

また、SSLのセットアップが正しく行われているかの確認は以下のコマンドです。

$ curl -vI https://my_domain

最後に、DNSが正しく設定されているかの確認です。

$ heroku domains -a my_app
=== my_app Heroku Domain
my_app.herokuapp.com

=== my_app Custom Domains
Domain Name    DNS Target
──────   ────────────
my_domain      dns_target.com
$ dig my_domain cname +short
dns_target.com.

このようなレスポンスがあれば正しく設定されていますが、グローバルに反映されるにはタイムラグがあるようなのでそこには注意しましょう。
これで証明書の反映は完了です。

以上、少し長くなってしまいましたが、Let's Encryptで取得したSSL証明書を、Herokuで公開しているアプリケーションに反映させた話でした。
少々ややこしいですが、これで個人のドメインにも証明書を反映させることができます。更新時の自分の役に立てばいいのですが。

MonacaでiOSアプリをビルドしてみた

MonacaiOSアプリをつまづきながらもビルドした話です。
公式ドキュメントに手順が詳しく記載されていますが、自分の中での手順再確認も兼ねて、記事にしてみます。
例によってMonacaiOSに関しては初心者もいいところなので、書き方が変だったり言葉を誤って使用していたりするかもしれません。ご了承ください。

Monacaは、スマートフォンなどで動作するモバイルアプリを、HTML、CSSJavaScriptを使ってクラウド上で作成できる開発環境です。Apache Cordovaというハイブリッドアプリのフレームワークを利用しています。
ハイブリッドアプリ、Cordovaについての解説は、本題からそれるため省略します。気になる方は調べてみてください。

さて、何故僕がMonacaiOSアプリをビルドすることになったのか、そこから説明しようと思います。
まず、Cordovaには、ネイティブ機能を提供するプラグインというものがあります。必要なネイティブ機能、例えばカメラの起動やバイブレーションの動作などに合ったプラグインを組み込むことで、そのネイティブ機能をJavaScriptで呼び出せるようになります。
カメラの起動やバイブレーションの動作のような、基本的な機能を提供するプラグインは、基本Cordovaプラグインとして用意されており、気軽に使うことができます。しかし、それだけではネイティブアプリのような高度な機能を持ったアプリは実装できません。
ではどうすればいいのか。自分に必要なネイティブ機能を提供するプラグインを自分で作成してそれを組み込めばいいのです。今回は、プラグインを作成したのは別の人でしたが、そのプラグインiOSアプリ上で期待通りの機能を提供してくれるかの検証を、僕が行うことになりました。

参考:ユーザーCordovaプラグイン

Monacaは開発者向けにデバッガーを提供しているため、これを使えば簡単に検証できると、最初はそう思っていました。早速ストアからダウンロードして、動作を確認してみます。ところが、何度試してみても、検証したい機能が動作してくれません。
こういうときは公式ドキュメントを読んでみます。先ほどもちょっと触れましたが、Monacaは公式ドキュメントがかなり充実しているように思います。
公式ドキュメントを読んでみると、ちゃんと書いてありました。ストア版のデバッガーには、自作のプラグインが実装されていないため、デバッガー上でアプリをそのまま実行しても、正しく動作しません。そこで、ストア版のデバッガーの代わりに、カスタムビルド版のデバッガーを使用する必要があるとのことです。カスタムビルド版のデバッガーは、文字通りMonacaクラウドIDE上でビルドして端末にインストールするものなので、プラグインの検証を行うためには、iOSアプリのビルドが必要不可欠ということがわかりました。
また、デバッガーを使用しない場合でも、デバッグビルドというビルドが必要になるようです。
少し長くなってしまいましたが、以上が僕がMonacaiOSアプリをビルドすることになった理由です。

それでは本題、MonacaiOSアプリのビルドの手順に移ります。
手順を知りたい場合は、やはり公式ドキュメントを読むのが確実です。というかMonacaで何かする方法を検索してみてもヒットするのは公式ドキュメントばかりで、個人ホームページやブログは全くと言っていいほどヒットしません。公式ドキュメントが充実している証拠でしょうか。
というわけで、公式ドキュメントのカスタムビルド版Monacaデバッガーのビルド方法と、iOSアプリのビルドを参考に進めてみます。

まず、MonacaクラウドIDE上で、設定→iOSアプリ設定でiOSアプリの設定画面を開き、アプリケーション名、App ID、バージョンを入力します。今回の目的はデバッグなので、アプリケーション名は適当で大丈夫そうです。短くてわかりやすい名前をつけてあげましょう。バージョンもやはり適当で大丈夫なはずです。もちろんチーム内などでルールがある場合は、そのルールに従う必要がありますが。
App IDは要注意です。この後にiOS Dev Center上でApp IDを登録するのですが、そのときにこのApp IDを登録することになります。

続いて、設定→iOSビルド設定でiOSビルドの設定画面を開き、秘密鍵を生成します。ここではユーザー名と、Apple IDとして使用しているメールアドレスを入力します。
秘密鍵を生成すると、その秘密鍵に関連付けられたCSRファイルも生成されます。これは次のステップでiOS Dev Center上で証明書を発行するのに必要になるので、エクスポートしてどこかに保存しておきます。"csr.certSigningRequest"というファイル名になっているので、別のものと区別できなくならないように注意しましょう。

次に、iOS Dev Center上で、証明書を発行します。今回はデバッグ用にビルドを行うため、配布用証明書ではなく、開発用証明書を発行します。
Certificates→Developmentを選択し、追加ボタンを押し、iOS App Developmentを選択し、先ほど保存しておいたCSRファイルをアップロードすることで、開発用証明書が発行されます。
発行された開発用証明書は、次のステップでMonacaクラウドIDEにアップロードするので、どこかに保存しておきます。"ios_development.cer"というファイル名になっているので、こちらも別のものと区別できなくならないように注意しましょう。

今度はまたMonacaクラウドIDEに戻り、開発用証明書をアップロードします。公式ドキュメントにはどこにどうやってアップロードすればいいのか書かれていないため、要注意ポイントです。
先ほど秘密鍵を生成したiOSビルドの設定画面を開き、下の方にある証明書のアップロードのもう少し下、デベロッパー証明書のところにアップロードします。今回はデバッグ用にビルドを行うため、ディストリビューション証明書は必要ないはずです。

次はまたiOS Dev Centerに移り、App IDと開発用端末を登録します。それぞれ登録の作業が必要になるので、App IDから順番に説明します。
まずApp IDの登録です。Identifiers→App IDsを選択し、追加ボタンを押します。App ID Descriptionは、自分がわかりやすい説明を記入します。僕は先ほどMonacaクラウドIDE上で設定したアプリケーション名にしました。App ID Prefixはデフォルトです。App ID Suffixは要注意です。Explicit App IDを使う場合でも、Wildcard App IDを使う場合でも、先ほどMonacaクラウドIDE上で設定したApp IDとマッチするようにする必要があります。
例えば、MonacaクラウドIDEで入力したApp IDが"com.hoge.fuga"だった場合、Explicit App IDを使う場合は"com.hoge.fuga"にする必要がありますし、Wildcard App IDを使う場合は"com.hoge.*"のようにする必要があります。僕はExplicit App IDを使ったので、Wildcard App IDの方はよくわかりませんが、多分こういうことだと思います。
ちなみにここでApp IDを間違えると、後でビルドがコケます。ガックリ。
さて続いて開発用端末の登録です。Devices→iPhoneを選択し、追加ボタンを押します。もちろん開発用端末がiPhoneではない場合はiPhone以外のどれかを選択します。Nameは、自分が端末を区別しやすいように名前をつけてあげます。UDIDは、開発用端末のUDIDを入力します。
UDIDを確認する方法も説明しておきます。まず、開発用端末をコンピューターに接続し、iTunesを起動します。次に、iTunes上で端末のシリアル番号が表示されている箇所をクリックします。すると、UDIDが表示されるので、そこを右クリックしてコピーを選択します。コピーしたら、それをUDIDの欄にペーストしてあげれば完了です。

続いて、プロビジョニングプロファイルを作成します。開発用と配布用の2種類ありますが、例によって今回はデバッグ用にビルドを行うため、開発用のプロビジョニングプロファイルを作成します。
Provisioning Profiles→Developmentを選択し、追加ボタンを押します。DevelopmentはiOS App Developmentを選択し、次に進みます。App IDは先ほど登録したApp IDを選択します。Select certificatesでは、先ほどMonacaクラウドIDE上で秘密鍵を生成したときに入力したユーザー名を選択してあげれば大丈夫です。Select devicesでは、やはり先ほど登録した開発用端末を選択します。最後に、このプロファイルに名前をつけます。僕はApp IDのときと同様、アプリケーション名にしました。
作成したプロビジョニングプロファイルをダウンロードします。これも次のステップでMonacaクラウドIDEにアップロードするので、どこかに保存しておきましょう。ファイル名は"[プロファイル名].mobileprovision"のようになっているので、紛らわしい名前をつけていなければ他のプロファイルとの区別は容易です。

最後に、MonacaクラウドIDE上でアプリをビルドします。
ビルド→iOSアプリのビルドで、iOSアプリのビルド画面を開き、デバッグビルドか、デバッガーのビルドを選択します。次に、先ほどダウンロードしたプロビジョニングプロファイルを選択し、アップロードします。
プロビジョニングプロファイルを作成する際に、Select certificatesで他のユーザー名を選択してしまった場合、ここでエラーメッセージが出るので、確認が必要です。
ビルドが完了するまでしばらく待ちます。無事に終わったら、アプリをダウンロードします。ダウンロードしたアプリのアイコンをiTunes上にドラッグして、ライブラリに追加して、端末にインストールします。これで、ようやく自作のCordovaプラグインの検証を行うことができます。長い道のりお疲れさまでした!

ここからちょっと余談になります。
実は、今回の検証で、デバッグビルドはできるものの、カスタムビルド版のデバッガーはビルドできない状態に陥っていました。動作の検証自体はデバッグビルドでも行えるので大丈夫と言えば大丈夫なのですが、コールバックに、

console.log('hoge');

のようなものがある場合、それを確認するにはカスタムビルド版のデバッガーが必要になります。
検証対象となるプラグインを組み込まないでデバッガーのビルドを行うと、問題なくビルドできるので、原因はプラグインにあるところまで突き止めました。
そのことをプラグインの開発者に伝えたところ、どうやらプラグインで使っているライブラリとMonacaデバッガーで使っているライブラリが衝突してしまっていたのが原因だったようです。
もしデバッグビルドはできるのにデバッガーのビルドはうまくいかないという方がいらっしゃいましたら、そこを確認してみると良いと思います。僕はプラグインの開発には関わっていないため、具体的に何をどうすればいいのかまではわかりません。すみません。

以上です。やたら長くなってしまいましたが、MonacaiOSアプリをビルドした話でした。