Edited at

RubyMineからVagrantのサーバに対しリモートデバッグ

More than 3 years have passed since last update.

前回のエントリで、Vagrantでruby2.1入りのCentOS6.5を作りましたので、その続きです。


20160815: 更新情報

Vagrant内でのRailsの起動そのものが遅い場合の情報を追記しました。


20160427: 更新情報


  • このエントリでは、デバッグの素材としてRedmineを利用しています。スクラッチのRailsとは利用しているgemがいろいろと異なりますので、ご注意ください。

  • シンプルなRailsアプリケーションで試す場合も基本は同じですが、デバッグが途中でエラーやSegmentation faultになることがありました。末尾に情報を付加しておきます。


やりたいこと / 確認したいこと


  • RubyMineでリモートデバッグをしてみたい(やったことがない)


    • ただし自分のMacはあまり汚したくない

    • Vagrantを使ったOSに対しリモートデバッグしたい



  • Vagrantのサーバ側がruby2.1, RubyMine側はrbenvでruby2.0をデフォルトにしてるけど、大丈夫なのかな?

  • リモートデバッグだけじゃなくて、ソースコードも都度変えてみたいけど、どうすればいいかな?

ということで、チャレンジ。

素材はいつもの通りRedmineです。(自作Railsアプリは皆無なのですが、Redmineのプラグインの動作チェックをすることが多いので)


Vagrantfileの調整

Redmine稼働は、手っ取り早くsqlite3を利用します。このため、yumでsqlite用のパッケージ追加が必要になりますので、config.vm.provisionのステップに追加するか、vagrant sshしてから追加します。


  • 前提条件:


    • ポートフォワードではなく、VirtualBoxの仮想ネットワークを利用し、固定IPで接続。

    • 今回のIPは192.168.33.11

    • Firewallは切っておく。



※Vagrantfileは、このエントリの末尾の『メモ』に載せておきます。


Redmineのソースの配置

Mac側からも、VagrantのCentOS側からも同じソースを扱えるように、RedmineのソースをMacOS(ホスト)側のVagrantfileを設置したのと同じディレクトリに展開します。

# MacOS (ホスト)側

% uname
Darwin
% ls
Vagrantfile server_spec redmine-2.3.4

# CentOS (ゲスト)側にログインして確認
% vagrant ssh
Last login: Sun Jan 26 13:59:51 2014 from 10.0.2.2
[vagrant@test ~]$ ls /vagrant/
Vagrantfile redmine-2.3.4 server_spec

同じものが見えました。


Gemfileを調整する

リモートデバッグが出来るように、ruby-debug-ide を入れます。

また、bundle install --path 指定し、gemをredmineのソースディレクトリの直下に入れることにします。

Gemfileに下記を追加。

gem 'ruby-debug-ide'

gem 'debase'


Redmineのセットアップ (ゲストOS側)

Gemfileを調整し、--pathをしてbundle install実施。

(bundle execだと結構時間がかかりました…)

[vagrant@test redmine-2.3.4]$ bundle install --path vendor/bundler --without mysql postgresql rmagick

# ひたすら待つ

うまく入ったら、database.ymlを作成し、migrateします。

[vagrant@test ~]$ cat /vagrant/redmine-2.3.4/config/database.yml

development:
adapter: sqlite3
database: db/test.sqlite3

# redmineのソースディレクトリに移動してから
[vagrant@test redmine-2.3.4]$ bundle exec rake db:migrate
[vagrant@test redmine-2.3.4]$ bundle exec rake generate_secret_token

ここまでで、bundle exec rails sで、最低限Redmineをポート3000で起動できる環境ができました。

次に、ホストOS側: RubyMine側の設定に移ります。


RubyMine側のセットアップ (ホストOS側)


ゲストOSと共有しているredmineのソースディレクトリを指定

今回使ったのは、RubyMine6.0です。

下記のように、リモートデバッグ用のプロジェクトを作成しました。

(お作法的に正しいのか分かりませんが、とりあえず試行錯誤の結果、動作した手順を記載します)


  • RubyMineから新規プロジェクト作成。


    • 既存のRailsアプリケーションを利用する。



  • ホストOS側では、bundle execとかmigrationの作業はしなくて良い。


    • ホスト側ではリモートデバッグのみで、ホスト側でのRedmine起動はしないので。




リモートデバッグ用の設定を追加


  • メニューから、『Run』 -> 『Edit Configurations』の画面を開く。

  • 画面左の『+』マークを押して、『ruby remote debug』を選択。

  • Setting セクションの調整をします。


    • Vagrant側とはポートフォワードであれば、特に変更の必要は無し。

    • わたしの場合は192.168.33.11を明示的に割り当てているので、hostに指定。

    • Remote root folder: /vagrant/redmine-2.3.4

    • Local root folder: (Vagrantfileが置いてあるディレクトリのredmine-2.3.4)



下記が、Remote Debug用の設定のスクリーンショットです。


Remote Debugを実施してみます

ホストOS側のRubyMineも準備が出来たので、実際にリモートデバッグが出来るかやってみます。


アプリケーションの起動(ゲストOS側)

[vagrant@test redmine-2.3.4]$ bundle exec rdebug-ide --port 1234 --dispatcher-port 26162 --host 192.168.33.11 script/rails s

Fast Debugger (ruby-debug-ide 0.4.22, debase 0.0.9) listens on 192.168.33.11:1234
![rubymine-remote-debug.png](https://qiita-image-store.s3.amazonaws.com/0/27976/a55c1421-f935-f683-03c4-03c3978bb3f6.png "rubymine-remote-debug.png")

# WebRickが上がるまでしばらく待つ…
=> Booting WEBrick
=> Rails 3.2.13 application starting in development on http://0.0.0.0:3000
=> Call with -d to detach
=> Ctrl-C to shutdown server

# INFOが出て来たらアプリケーションへのアクセス可能
[2014-01-26 15:09:09] INFO WEBrick 1.3.1
[2014-01-26 15:09:09] INFO ruby 2.1.0 (2013-12-25) [x86_64-linux]
[2014-01-26 15:09:09] INFO WEBrick::HTTPServer#start: pid=2391 port=3000

INFOのログが出て来たら、ブラウザから3000番を指定して、Redmineのアクセスが出来ます。


RubyMine側でRemote Debug開始(ホストOS側)

RubyMineの『Run』メニューから、先ほど作ったRemote Debugを実行します。

上手く行くと、画面下にデバッガの制御やコンソールの画面が出て、"Connected" になります。


ブレークポイントを指定してみる

では、適当なファイル(今回は、View用のerb)にブレークポイントを指定して、ブラウザをリロードしてみます。

上手く行くと、ちゃんとブレークポイントで停止し、変数も画面から確認できます。


ソースを修正してみる

共有フォルダの機能でRedmineのソースはゲストOS側と同期するはずなので、RubyMine側からファイルを修正してみます。

今回は、デフォルトのタイトルの部分に、『テスト用の文字列追加』という文言を加えてみました。(base.html.erb)

画面をリロードしてみると…。

一応想定通りの動作をしてくれたようです。


まとめ

まだほんの少しだけですが、Vagrantを利用して、RubyMineからのリモートデバッグが出来るようになりました。また、/vagant (共有フォルダ) を介してのソースの修正もできそうなことが分かりました。

Redmineのセットアップ自体も、config.vm.provisionで出来なくもなさそうですが、こちらは手で作業して上手くいったら、config.vm.provisionに少しずつ追加したり、Chef化したりするのが良さそうです。

なお、RubyMineでのリモートデバッグの情報をチェックした際に、YouTubeの下記の資料を見つけました。

次はこちらも試そうと思います!

ひとまずこの段階でのスナップショットを取得して、終わりとします。

% vagrant snapshot take redmine-debug-enabled

Taking snapshot redmine-debug-enabled
0%...10%...20%...30%...40%...50%...60%...70%...80%...90%...100%


メモ:今回のVagrantfileの設定

# -*- mode: ruby -*-

# vi: set ft=ruby :

# Vagrantfile API/syntax version. Don't touch unless you know what you're doing!
VAGRANTFILE_API_VERSION = "2"

Vagrant.configure(VAGRANTFILE_API_VERSION) do |config|
# All Vagrant configuration is done here. The most common configuration
# options are documented and commented below. For a complete reference,
# please see the online documentation at vagrantup.com.

# Every Vagrant virtual environment requires a box to build off of.
config.vm.box = "cent65"
config.vm.box_url = "https://github.com/2creatives/vagrant-centos/releases/download/v6.5.1/centos65-x86_64-20131205.box"
config.vm.hostname = "test"
config.vbguest.auto_update = false
config.vm.network :private_network, ip: "192.168.33.11"

config.vm.provider :virtualbox do |vb|
vb.customize ["modifyvm", :id, "--memory", "2048"]
vb.customize ["modifyvm", :id, "--cpus", "1"]
end

config.vm.provision :shell, :inline => <<-EOT
echo "config.vm.provision :shell start!"
yum install -y gcc
yum install -y zlib-devel openssl-devel
cd /usr/local; curl -OL http://cache.ruby-lang.org/pub/ruby/2.1/ruby-2.1.0.tar.gz
cd /usr/local; tar xfz ruby-2.1.0.tar.gz
cd /usr/local/ruby-2.1.0; ./configure --prefix=/usr/local; make; make install
/usr/local/bin/gem install bundler --no-ri --no-rdoc
# 以下2つは便利なのでいつも追加してます
yum install -y locate
yum install -y tree

# For Redmine
yum install -y sqlite sqlite-devel
# For Nokogiri (Nokogiri is required Redmine)
yum install -y libxml2-devel libxslt-devel
EOT
end


リモートデバッグが上手くいかなかった時(20160427追記)

いくつか考えられますので、確認してみてくださいね。


Firewallがデバッグ用のセッションを通さないようになっている


  • Vagrant側でポートフォワードさせていても、Macのファイアウォールやセキュリティソフトの設定で、通信がブロックされている場合は、うまく動きません。最後の最後にどうしても思い当たることが無い場合は、設定を確認してみてください。


デバッグのセッションは開始されるんだけど、途中で停止してしまう


  • この場合は、Gemfileに以下のブロックがあったら、コメントしてみてください。

  • ruby-debug-ide と併用すると上手く動かない場合があるようです。

  • byebugもデバッグgemです



group :development, :test do

# Call 'byebug' anywhere in the code to stop execution and get a debugger console
gem 'byebug' # ここをコメント扱いにする
end


Segmentation faultでサーバ側のプロセスが落ちた!


  • こちらは再現性がよく分からないのですが、以下のようなメッセージが出て、デバッグ途中でプロセスが落ちることがありました。

  • ruby2.3.0でのバグのようですが、自分では解決できそうになかったので、保留...

  • ruby2.2.4に下げて動かしたところ、大丈夫でした

pell_checkers/name_error_checkers/variable_name_checker.rb:10: [BUG] Segmentation fault at 0x000000000000f9

ruby 2.3.0p0 (2015-12-25 revision 53290) [x86_64-linux]

-- Control frame information -----------------------------------------------
c:0108 p:---- s:0567 e:000566 CFUNC :local_variables


リモートデバッグはできるんだけど、ものすごく遅い!(201608215追記)

VagrantとホストOS側とのファイル共有をし、ソースディレクトリをRubyMineで開いてリモートデバッグしている際、非常に処理が遅くて困ることがありました。

リモートデバッグにかかわらず、Vagrantを使ってのRails起動が遅い...といった場合の対処法として、こちらも合わせてどうぞ。


IntelliJ IDEAでもリモートデバッグできるの?

基本は同じなので、プラグインを追加してSDK (ruby) 周りの設定を追加すればIntelliJ IDEAでもrailsのアプリケーションのリモートデバッグができます。

ただし、開発の中心がrubyで、その他の言語はあまりつかわない場合は、RubyMineに絞って利用したほうが使い易いと思います。