RubyMine 2019.1でRailsをdocker exec経由で起動可能になったがバグあって使い物にならない件

RubyMine 2019.1でRailsをdocker exec経由で起動可能になったがバグあって使い物にならない件

こんにちは。皆さんは普段どのような開発環境を使っていますか?僕はJetBrainsのIDEが好きなので、All Products Licenseを購入して各プロジェクトごとに適したIDEを愛用しており、RubyではRubeMineを使用しています。

さて、そんなRubyMineですが先日今年初のメジャーリリースである2019.1がリリースされ、以前はできなかったDocker Remote Interpreterでのプロセス起動が、 (docker runだけでなく) exec経由でも起動できるようになった様なので、試してみました。

※RubyMineのDockerインテグレーションはまだまだ詰めが甘い所が多く、不具合が多いので使い物になるレベルでは無いと個人的に思っています。現にこの記事で紹介しているサンプルもまともには動きません。なので今回はあまり身になる記事となっていないですがご了承下さい。

2018.xでのDockerサポート状況

実際JetBrains IDEではDockerおよびDocker Composeのサポート自体はされてからだいぶ久しく、RubeMineでもRemote InterpreterとしてDockerコンテナを指定する事はこれまでもできていました。
しかし、いずれもdocker runまたはdocker-compose run経由で、特にDocker Composeの方はIDEが自動生成した拡張 docker-compose.yml ファイルを使ってVolume設定等をオーバーロードさせる仕様であった為に、(元が複雑な docker-compose.yml だと)使いづらい仕様でした。

ところが、今回の対応で新たにdocker(-compose) exec経由でコンテナ内のrubyプロセスを起動できる様になった為、以前よりは使いやすくなったかと思います。

実際に試してみた

JetBrainsが今回の機能をテストする為のテストリポジトリを公開しているので、これを使っていきたいと思います:

Ruby on Rails Tutorial sample application

適当な所にCloneします:

git clone git@bitbucket.org:rubyminedoc/sample_rails_app_docker.git
cd sample_rails_app_docker

デフォルトでは、データストアとしてSQLite (docker run 経由での実行テストの為) が指定されているので、 config/database.yml を編集してPostgreSQLが使われるようにします。
具体的には、コメントアウトされている development の設定のコメントアウトを外し、元の development 設定を削除します:

# ...

development:
  <<: *default
  adapter: postgresql
  encoding: unicode
  host: db
  username: postgres
  password:
  database: sample_rails_app_db

# # ...

それではdocker-composeしてみましょう:

docker-compose up -d

初回はイメージのビルドが入るので少し時間が掛かります。
しばらくすると、 web (Rails) と db (PostgreSQL) の2サービス (コンテナ) が立ち上がります。

ただし、このままではブラウザでアクセスができません。 docker-compose.yml を見てみると分かるのですが、 web サービスのcommandが tail -f /dev/null (※1) となっており、Railsは起動していない為です。
Railsのプロセスをdocker-compose execで起動する為にこのような設定となっています。

※1: tail -f /dev/null はコンテナ技術でよく使われる、何もしないDAEMONである。

RubyMineのRemote Interpreterを設定

起動した web コンテナの中の ruby コマンドをRubyMineから呼び出す為、Remote Interpreterを設定します。

Dockerのとの連携自体がまだの場合、先に行っておく必要があります。

File (メニュー) -> Preference -> Build, Extension, Deployment -> Docker で追加できます。
Docker for Macを使ってる場合、設定ペインの「+」を押した後デフォルトの設定で即使えるので便利です。

Preference -> Languages & Framework -> Ruby SDK and Gems を開きます。
設定ペインの「+」で新規追加をしますが、ここで “New Remote…” を選択してください。

表示された “Configure Remote Ruby interpreter” ダイアログで、 “Docker Compose” を選択し、Serviceを “web” にして設定を行います。

“OK” を押すとRemote Interpreterの追加とGemのDL&インデクスが行われます。(これもちょっと時間が掛かります)

その後、Edit Path Mappingsの設定を行いましょう。「+」と同じツールバーの一番右端のアイコンをクリックします。

開かれた “Edit Project Path Mappings” と言うダイアログで、Local Pathをプロジェクトルートに、Remote Pathを “/sample_rails_application” とします。

設定ができたら早速使ってみましょう。先程言った通り、Railsは動いていませんが、Railsを動かす為のコンテナ自体は動いています。
Railsアプリケーションを動かす前にDBの初期化が必要なので、それだけ先に済ませておきたい所ですが、せっかくなので追加したRemote Interpreter経由で動かしてみたいと思います。

Tool (メニュー) -> Run Rake Task で出てきたダイアログで db:migrate:reset を実行します。ちなみに、初回の実行時は “[Reload rake tasks list]” が必要なのでご注意ください。

更に “Execute db:migrate:reset” と言うダイアログが表示されますが、そのまま “OK” を押すと、マイグレーションの初期化が行われます。

Railsの起動

いよいよRailsの起動です。Runの設定 (Edit Configuration) 開きます:

Rails -> Development: sample_rails_app_docker を選択肢、画面下部の “docker-compose” が “docker-compose exec” になっている事を確認します:

問題がなければ、 Run (メニュー) -> Run で起動してみます。
コンソールを見た感じ、無事に起動しているようです。

ブラウザで http://127.0.0.1:3000 を開くと画面が表示されました:

ここで起動したRailsのプロセスは一旦終了しておきましょう。

リモートデバッグを試してみる

デバッグもできるようなので試してみましょう。Gemfileを開き、 debase と ruby-debug-ide のコメントアウトを外します:

group :development, :test do
  gem 'sqlite3', '1.3.13'
  gem 'byebug',  '9.0.6', platform: :mri
  gem 'debase'
  gem 'ruby-debug-ide'
end

そのまま Tool (メニュー) -> Bundler -> Install で起動中のコンテナ内でGemのインストールが行なえると言う事なのですが、起動中のコンテナ内で実行される訳ではない (代わりに RUBYMINE_SDK_CONTAINER_xxx と言うコンテナの中で実行される) と言う謎な仕様の為、このままではデバッガを動かせないので、docker-compose up -d --build も同時に行っておく必要があります。(※1)

再度インデクスが始まるので、それを待った後いよいよ実行するのですが、そのままでは行なえません。
その理由は、ruby-debug-ideを使ってRemote Debugをする場合、 ホストからコンテナにポート 123426162 でTCP接続できる必要があるからです。しかし、 docker-compose.yml はそうなっていません。なので、ついでにその設定も変更が必要です (なのでその後に docker-compose up -d --build しましょう):

# ...

  web:
    # ...
   ports:
      # ruby-debug-ide 用
      - "1234:1234"
      - "26162:26162" 
      # rails用
      - "3000:3000" 
# ...

それでは気を取り直して Run (メニュー) -> Debug をしてみます。
※初回起動時は server.pid が無いとかでエラーになる場合がありますが、その場合は普通の Run を一旦実行しておくと解消します。

http://127.0.0.1:3000/ を開くと、先程の画面が見れます。

それでは試しに UserController#index にBreakpointを置いてみましょう:

画面をリロードすると、無事・・・止まりません

2019.1の不具合について

なんと、2019年4月15日時点で、肝心のBreakpointによるステップ実行が機能していないのです。
しかも、この不具合は以前 (僕の記憶だと半年くらい前) からあり、YouTrackで “docker breakpoint” と検索すると、RubyMineでは以前からDocker Remote Interpreterによるデバッグ機能の不具合がある事が分かります。

https://youtrack.jetbrains.com/issues/RUBY?q=docker breakpoint

と言う訳で、現時点ではリモートデバッグは諦めるしか無さそうです。と言ってもIssueが放置されてる物もあり、復旧の見込みはありませんが・・・。

因みに、Dockerを使わずローカルでrbenvとか使ってる場合は問題なく動作するので、しばらくRubyMineで(Railsを)Dockerで起動するのは諦めた方が良いかもです。

※1: docker-compose up -d --build だけだとRubyMineが追加されたGemをダウンロードしないので、その後のデバッグが行えない。またこの件は既にIssueが立ててあった: https://youtrack.jetbrains.com/issue/RUBY-23872

まとめ

今回、RubyMineのメジャーアップグレードでDockerインテグレーションが強化されたとの事ですが、まだまだ不十分な部分があり、以前からある不具合も解消されていないので、使い物にはならない品質と言えます。
YouTrackの方もあまり有意義な議論がされていないので、皆さんもどしどし報告すれば運営も動いてくれるかもしれません。

PhpStormやIntelliJ IDEAは更新も早いしバグもすぐ修正されるのですが、RubyMineはなぜあのような不遇な扱いを受けているのでしょうか・・・。

今回はあまり身になる記事を書けなくて残念でしたが、JetBrainsもRubyも好きなので早く治ってくれる事を願います。

we are hiring

優秀な技術者と一緒に、好きな場所で働きませんか

株式会社もばらぶでは、優秀で意欲に溢れる方を常に求めています。働く場所は自由、働く時間も柔軟に選択可能です。

現在、以下の職種を募集中です。ご興味のある方は、リンク先をご参照下さい。