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


[前回のエントリ](http://qiita.com/akiko-pusu/items/94fb57ea002ed8c73d3c)で、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のソースディレクトリの直下に入れることにします。

- 参考 / RubyMine 6.0.0 Help - Remote Debug
 - http://www.jetbrains.com/ruby/webhelp/remote-debugging.html

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](https://qiita-image-store.s3.amazonaws.com/0/27976/83381cd6-58fc-57e4-4921-8190bc424b3a.png "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](https://qiita-image-store.s3.amazonaws.com/0/27976/9d860b09-108b-6139-e6be-318a30d59f18.png "rubymine-remote-debug.png")


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

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


![rubymine-remote-debug2.png](https://qiita-image-store.s3.amazonaws.com/0/27976/366561ab-fe45-7b47-2ca7-865628d8abeb.png "rubymine-remote-debug2.png")

#### ソースを修正してみる

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

![rubymine-remote-debug3.png](https://qiita-image-store.s3.amazonaws.com/0/27976/23d3a7ce-e696-bedf-5842-25d6324bc6b9.png "rubymine-remote-debug3.png")

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

## まとめ

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

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

なお、RubyMineでのリモートデバッグの情報をチェックした際に、YouTubeの下記の資料を見つけました。
次はこちらも試そうと思います！

- RubyMine and Vagrant / YouTube
 - http://www.youtube.com/watch?v=5KQUhMM_99Y
 - *Anna Bulenkova is talking on how to configure Vagrant and use it as a remote interpreter in RubyMine.*

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

```
% 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です
 - Ref. [RailsGides: Rails アプリケーションのデバッグ](http://railsguides.jp/debugging_rails_applications.html)


```
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起動が遅い...といった場合の対処法として、こちらも合わせてどうぞ。

- [Vagrantのshare folderが遅い時はNFSを使うといいです](http://qiita.com/itopan88/items/06d7c7a08f2d681b042a) (itopan88さんの記事)

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

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

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