以前、Herokuにて.NETのbuildpackを使ってNancyをデプロイしてみました。
C# + NancyでJSONを返すWebアプリを作り、Heroku Buttonを使ってHerokuへデプロイしてみた - メモ的な思考的な
そんな中、.NET(Mono)環境でもRakeタスクを使いたくなったため、いろいろと試してみた時のメモを残します。
環境
- Windows7 x64
- RubyInstaller 2.1.5
- gemの
Bundler
をインストール済
- gemの
- .NET Framework 4.5
- Heroku toolbelt
- Herokuのbuildpack
流れ
HerokuのMono環境にて、Rubyの確認
HerokuにNancyアプリをデプロイした時は、Monoのbuildpackを使っていました。
ただ、その状態ではRubyは動作しているようですが、gemは何もインストールされていませんでした。
$ heroku run ruby -v --app (AppName)
Running `ruby -v` attached to terminal... up, run.1735
ruby 1.9.3p484 (2013-11-22 revision 43786) [x86_64-linux]
$ heroku run gem list --app (AppName)
Running `gem list` attached to terminal... up, run.6192*** LOCAL GEMS ***
当然ながら、Rakeを実行しようとしてもエラーになります。
$ heroku run rake --app (AppName)
Running `rake` attached to terminal... up, run.1763
bash: rake: command not found
また、新しくgemをインストールしようとしても、実行できませんでした。
$ heroku run gem install rake --app (AppName)
Running `gem install rake` attached to terminal... up, run.4633
Fetching: rake-10.4.2.gem (100%)
ERROR: While executing gem ... (Errno::EROFS)
Read-only file system - /var/lib/gems
HerokuにMono環境とRuby環境を用意
以上より、Mono環境だけではRakeタスクを実行できませんでした。
そこで、何か良い方法がないかを探したところ、複数の言語を利用できるようになるheroku-buildpack-multi
を使い、MonoとRubyの2つの環境を用意すれば良さそうでした。
Ruby - Herokuのapp作成手順(buildpack-multiを使う場合も含む) - Qiita
.buildpacks
ファイルの用意
heroku-buildpack-multi
を使うため、.buildpacks
ファイルを用意します。
その中では、 heroku-buildpack-ruby
とheroku-buildpack-mono
のbuildpackを使用するように指定します。
https://github.com/heroku/heroku-buildpack-ruby.git https://github.com/friism/heroku-buildpack-mono.git
Gemfile
とGemfile.lock
の用意
heroku-buildpack-rubyによるRuby環境を構築する場合、Gemfile
とGemfile.lock
がないと、それぞれ次のようなエラーが発生します。
Gemfileがない場合
remote: =====> Downloading Buildpack: https://github.com/heroku/heroku-buildpack-ruby.git
remote:
remote: ! Push rejected, failed to compile Multipack app
remote:
remote: Verifying deploy...
Gemfile.lockがない場合
remote: =====> Detected Framework: Ruby
remote: -----> Compiling Ruby/NoLockfile
remote: !
remote: ! Gemfile.lock required. Please check it in.
remote: !
remote:
remote: ! Push rejected, failed to compile Multipack app
buildpackのFlowに次のように書かれていたため、エラーになったのかなと思いました。
Ruby (Gemfile and Gemfile.lock is detected)
heroku/heroku-buildpack-ruby · GitHub
そのため、まずは以下の内容を持つGemfile
を作ります。
source 'https://rubygems.org'
続いて、Gemfile.lock
を作成するため、bundlerを実行します。
$ bundle install --path vendor/bundle
...
It was installed into ./vendor/bundle
Gitへコミット
- .buildpacks
- Gemfile
- Gemfile.lock
をGitリポジトリへとコミットします。
Herokuの環境変数を追加
heroku-buildpack-multi
を使うために、BUILDPACK_URL
へheroku/heroku-buildpack-multiのリポジトリのURLを環境変数へ追加します。
$ heroku config:add BUILDPACK_URL=https://github.com/heroku/heroku-buildpack-multi.git
Herokuへpush
$ git push heroku master
...
remote: Verifying deploy... done.
Rubyとgemを確認
Rakeが入っています。
$ heroku run ruby -v
Running `ruby -v` attached to terminal... up, run.9263
ruby 2.0.0p598 (2014-11-13 revision 48408) [x86_64-linux]
$ heroku run gem list
Running `gem list` attached to terminal... up, run.2250
*** LOCAL GEMS ***
bigdecimal (1.2.0)
bundler (1.6.3)
io-console (0.4.2)
json (1.7.7)
minitest (4.3.2)
psych (2.0.0)
rake (0.9.6)
rdoc (4.0.0)
test-unit (2.0.0.0)
Rakefileの用意と実行
上記までで環境ができたため、今度はRakeタスクを用意します。
今回はコンソール画面にHello Worldを表示するRakeタスクを持つRakefileを作成します。
desc "Task Test" task :hello do puts "Hello world" end
上記のRakefileをコミット・Herokuへpushし、Rakeタスクを実行します。
$ heroku run rake hello
Running `rake hello` attached to terminal... up, run.9131
Hello world
問題なくRakeタスクが実行できました。
また、Nancyアプリも動作しています。
ソースコード
GitHubに上げておきました。
thinkAmi-sandbox/NancyOwinHeroku-rake
Heroku Buttonも置いておきます。
なお、Nancyの部分はthinkAmi-sandbox/NancyOwinHeroku-sample · GitHub のコードをコピペして、必要なファイルを追加した形になっています。
その他
Windowsでgemをインストールしようとするとエラー
今回はGemfileがほぼ空っぽでしたが、何かgemを追加してbundle installすると、以下のようなエラーが発生することがあります。
$ bundle install --path vendor/bundle
DL is deprecated, please use Fiddle
Fetching source index from https://rubygems.org/
Retrying source fetch due to error (2/3): Bundler::Fetcher::CertificateFailureError Could not verify the SSL certificate for https://rubygems.org/.
There is a chance you are experiencing a man-in-the-middle attack, but most likely your system doesn't have the CA certificates needed for verification. For information about OpenSSL certificates, see bit.ly/ruby-ssl. To connect without using SSL, edit your Gemfile sources and change 'https' to 'http'.
あるいは、ローカルにgemをインストールしようとしてもエラーになります。
$ gem install bundler --no-ri --no-rdoc
ERROR: Could not find a valid gem 'bundler' (>= 0), here is why:
Unable to download data from https://rubygems.org/ - SSL_connect returned=1 errno=0 state=SSLv3 read server certificate B: certificate verify failed (https://api.rubygems.org/latest_specs.4.8.gz)
対応としては、httpsをhttpにするのではなく、以下を参考に新しい証明書ファイルをダウンロード・設定します。
Windowsでgem installするとSSLエラーが出る場合の解決策 - Qiita
なお、自分はデフォルトのインストール先でRubyInstallerを使っていますが、その場合は、以下のパスになっていました。
C:\Ruby21\lib\ruby\2.1.0\rubygems\ssl_certs
Heroku toolbeltを入れるとRubyが入るが、削除するとエラー
Heroku toolbeltをインストールすると、自分で入れたRubyInstaller2.1.5の他に、Ruby1.9.3p448もインストールされます。
このRubyを消してしまうとherokuコマンドが以下のエラーで動作しなくなりました。
$ heroku
/c/Heroku/bin/heroku: line 4: /path/to/ruby: No such file or directory
/c/Heroku/bin/heroku: line 4: exec: /path/to/ruby: cannot execute: No such file or directory