Redmine
vagrant
RubyMine

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

More than 1 year has 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用の設定のスクリーンショットです。

rubymine-setting.png

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" になります。

rubymine-remote-debug.png

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

では、適当なファイル(今回は、View用のerb)にブレークポイントを指定して、ブラウザをリロードしてみます。
上手く行くと、ちゃんとブレークポイントで停止し、変数も画面から確認できます。

rubymine-remote-debug2.png

ソースを修正してみる

共有フォルダの機能でRedmineのソースはゲストOS側と同期するはずなので、RubyMine側からファイルを修正してみます。
今回は、デフォルトのタイトルの部分に、『テスト用の文字列追加』という文言を加えてみました。(base.html.erb)
画面をリロードしてみると…。

rubymine-remote-debug3.png

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

まとめ

まだほんの少しだけですが、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に絞って利用したほうが使い易いと思います。