morimorihogeです。しばらく色々とバタバタしてしまっていまいほぼオンライン上のアクティビティが無になってしまっているのですが、生存報告ということで例年やっている夏のTechRachoフェア記事を投稿します。
今回はあまり知られていなさそうなJetBrains GatewayとJetBrains Projectorについて紹介します。
宣伝
本日より1ヶ月間、『夏のTechRachoフェア2021』と題して弊社のメンバーで入れ替わり記事を公開していきます。
企画としては冬に行われるアドベントカレンダーの夏バージョンで、普段あまり記事を書く機会のないメンバーにも記事を書くきっかけを作ろうという内容になります。弊社内、及び弊社にゆかりのある方の記事を公開していきますので、ぜひお楽しみ下さい。
過去の企画については以下に一覧しましたので興味のある方はどうぞ。弊社所属メンバーの雰囲気を垣間見られるかと思いますので、採用応募などを検討されている方はぜひ参考にして下さい。
- 2021冬のアドベントカレンダー
- 2021夏のTechRachoフェア
- 2020冬のアドベントカレンダー
- 2020夏のTechRachoフェア
- 2019冬のアドベントカレンダー
- 2019夏のTechRachoフェア
- 2018冬のアドベントカレンダー
- 2017冬のアドベントカレンダー
- 2016冬のアドベントカレンダー
ローカルで動かないRubyMine(他JetBrains IDE)が辛い話
みなさまご存じRubyMine(人によって他JetBrains IDEに読み替えて下さい)ですが、搭載するリッチな機能を利用しようとすると現代の開発では結構辛い現象が起きることがあります。
その主な原因はDockerコンテナ化やVM環境下が原因で、RubyMineを動かす場所とRailsプロセスを動かす場所が異なることが原因で起きるのですが、まずはその辺りから解説していきます。
理想的な環境(全て同一ホスト)
そもそもRubyMineが動作する最も理想的な(IDEにとって理想的な)環境は以下の図の様なケースです。
ここで大事なのは以下のポイントです。
- RubyMineはHost OS(LinuxやmacOS)のプロセスとして実行されている
rails
やrspec
プロセスはHost OS上で直接実行されており、RubyMineから「Run Command」などのIDEサポートを通じて実行する- ソースコードはHostマシン上のファイルとして存在し、NFSやSMBなどのネットワークファイルシステムを経由しないで動いている
- ちゃんとファイルロックが取れるし、Socketファイルなども作成できる。epollシステムコールを始めとするファイル監視系のシステムコールも理想的に動作する(ここ重要です。詳細は後述)
Dockerを使った場合
現代では環境構築の再現性からDockerを開発環境として使うことが増えました。すると、下図のような状態になります。
これにより理想的な環境に比べると以下のような変更が発生し、それぞれ辛みを産みます。
- RubyMineから
rails
/rspec
プロセスの実行がdocker run / docker exec経由になる- それらのプロセスがコンテナの中で実行されることで、ホスト側とのリソースが指定したもの以外共有されなくなる
- RubyMineのRSpec visualizerやDebuggerなどのGUIツール系(裏でプロセス間通信してデータの取得をしてるっぽい)がそのままだと動かないことがある
- ※正しく設定すればRubyMineが自動でDocker Compose configをパッチして動かして動作するはずだが、何かとハマりがち
- 各コンテナ環境から見えるソースコードはvolume mountしたパスのファイルになる
- ホストOSで動くRubyMine側でファイルを更新したイベントがコンテナ側に通知されなくなる
- fseventsなどを通じたホットリロードなどの動作に影響がある
RubyMineも別ホストになった場合
さらに、僕の最近利用しているWindows + WSL2 + Docker Desktopを使った開発環境だと、以下のような図になります。
※ファイルはWSL2上のLinuxに置き、WindowsのRubyMineプロセスからはネットワークドライブとしてマウントした \\wsl$
で始まるパスを開いて編集しています
すると、さらに以下の様な変更&辛みが出てきます。
- RubyMineの実行ホスト(Windows)とソースコードの実体があるホスト(WSL Linux)が別になる
- ソースコードアクセスが
\\wsl$
経由になる- WSL LinuxとWindows側のファイルアクセスの間には内部ネットワークを経由するため若干の遅延が発生する(が、ここはSSDの性能でゴリ押しすれば割となんとかなる。自分はSamsung 980 PROを使っています)
- RubyMineから見るファイルはWindows上のファイルとして見える
- ファイル更新時にbinstubs(binディレクトリ以下)のファイルから実行権限が消えてしまったり、Windows側のGit設定で
core.autocrlf
を有効にしていたりすると惨事を産みがち
- ファイル更新時にbinstubs(binディレクトリ以下)のファイルから実行権限が消えてしまったり、Windows側のGit設定で
- ソースコードアクセスが
- RubyMineの実行するDockerクライアントはWindows上から動かすDockerクライアントになる
- Windows上のファイルをvolume mountしたりしようとすると色々大変(自分はやらないようにしています)
辛い話まとめ
ここまで書いてきたことはそこそこ長くRubyMineを利用している人であれば誰もが一度は踏んだことのある辛みではないかと思います。
なお、RubyMineを動かしているHost OSではなくDocker経由やSSH経由でコマンドを実行する方法は公式からも提供されています。
これらの手順通り環境を適切に設定することができれば、前述したような環境でも理論上はローカルで動かすのと同じような感覚でRubyMineを利用できるはず・・・なのですが、実際にやってみるとひたすらハマります。
- SSHログイン時のログインメッセージがあるとバグってうまく動かない
- 個別に設定を作成した単純なコマンドのRunには成功するが、ソースコード中からのRSpecのRun(右クリックからの個別テスト実行など)がうまく動かないでタイムアウトする
- RSpecまでは完全に動くが、Debuggerがうまく動作しない、死ぬほど重い
- その他「昨日まで動いてたのに突然動かなくなる」こと多数
それぞれ時間を取って調べて行けば原因が分かることもあるのですが、トラブルシューティングには前述した図のあちこちの接続ポイントを疑ってデバッグしていく必要があり、自分のローカル環境の設定に依存した問題なども多かったりするのでとても初心者にはオススメできない状況に陥りがちです。
結局の所、RubyMineの動作環境と開発環境が同じOS内で動いていてくれれば楽なのに、そうなっていないというところに帰結するわけです。
救世主となるか!?JetBrains GatewayとProjector
ようやくJetBrains GatewayとJetBrains Projectorの紹介です。
これらのプロダクトは前述の問題を解決するためリモートホスト上でRubyMineのプロセスを実行し、手元環境にはUIの部分だけを転送して動かすということをやってのけるプロダクトです。
Web界隈に分かりやすいイメージとしてはE2Eテストで使うHeadless Chromeのような形でHeadless IDEを動かす、と言ったところでしょうか。
※なお、どちらもインストールするIDEのライセンスが必要です。クライアントインストール時と同じように評価用ライセンスも使えますが、常用する場合にはご注意ください
これらのプロダクトにより、従来よりもより開発環境に近い場所でRubyMineを動かすことができ、RubyMineから実行するプロセスやファイルアクセスについても手元環境ではなくリモート側で実行しているのと同じように動作させることができます。
両方そこそこ触ってみたので、それぞれざっと見ていきましょう。
JetBrains Gateway
SSH経由でHeadless RubyMineをターゲットホストで実行し、UIアプリケーションは手元で実行する形式。
触った感じのイメージとしてはX転送に近い・・・かもしれません。
- メリット
- SSHさえ繋がればすぐに使える導入の手軽さ
- UIはWindowsがレンダリングするので、Windowsのフォントやクリップボードを参照できる(重要)
- デメリット
- まだBeta(2022/08/01時点)で挙動が重め。特に初期インストールはそれなりに時間がかかる
- ターゲットホストのリソースをかなり食う(ターゲットでは普通にRubyMineを動かすので)ため、メモリ・CPU両方潤沢にないと厳しい
ちなみに、RubyMine以外のJetBrains IDEもサポートしています。現時点ではIntelliJ IDEA、CLion、GoLand、PhpStorm、PyCharm、Rider、RubyMine、WebStormが動作するようです。
JetBrains Projector(配布・サポート終了)
Dockerコンテナとしてブラウザでアクセスできるリモートデスクトップ + RubyMineがインストールされた専用デスクトップ環境が提供される形式です。
イメージとしてはブラウザからアクセスするという点でAWS Cloud9などのクラウドIDEサービスを使う感じに近いでしょうか。
デフォルトではport 8887で待ち受けるので、ブラウザでURLにアクセスするとRubyMineが起動してくれます。
- メリット
- 既存プロジェクトのDocker Composeに追記すれば動かせる手軽さ
- デメリット
- ここでアクセスできるRubyMineはあくまで
projector-rubymine
コンテナの環境なので、Rubyとか各種ライブラリ群が入っていない。開発環境として使うには、Projector用のDockerfileを用意して別途プロジェクト用にビルドしてあげる必要がありそう - フォントレンダリングが恐らくコンテナ側で行われているのか、クライアント側のインストールフォントが使えない
- IME周りは接続しているOSのものが動くようだが、ブラウザ通す以上UI周りでトラブる可能性はありそう
- ネットワーク経路はそのままだと暗号化されないので、外部サーバーとかで使うならproxyやlocalhost限定でLISTENしてSSHポート転送するなどの対応が必要
- ここでアクセスできるRubyMineはあくまで
こちらはお手持ちのDocker-Composeで管理されたプロジェクトに以下を足すだけでできるので、簡単に試せます。
※以下を追記して実行後、 http://localhost:8887
にアクセスすれば良い
# 2022/08/01現在、jetbrains/projector-rubymineが非公開になったので動きません。南無
services:
rubymine:
image: jetbrains/projector-rubymine
ports:
- "8887:8887"
volumes:
- .:/app
使ってみた感想など
JetBrains GatewayはIDEダウンロードが挟まる初回起動が遅かったりといった問題はありますが、一度起動してしまえば概ね問題無く利用でき、JetBrains的にも今力を入れているようでオススメです。
※なお、JetBrains Projectorの方はJetBrains公式のリリースとして開発はJetBrains Gatewayに引き継ぐため新たな利用は推奨されていません。 ※その後明示的にobsoleteされ、現在Docker Hub上での公開も停止しました。
これは僕の予想ですが、元々リモート開発環境の系譜としてJetBrains Projectorの開発は進んでおり、それとは別にコラボレーション開発手段として専用クライアントアプリを用いるCode With Meが開発されていましたが、ブラウザ上でデスクトップ環境と同じレベルまでUIを引き上げる方向よりも先にCode With Meが正式リリースできるレベルまで良い品質で完成してしまったので、リモート開発環境としては専用クライアントを使う方式一本にリソースを集中したのではないかと思います。
Code With Meは自分の手元で動かしているRubyMineの操作・閲覧権限を別の人に共有して同時編集・閲覧できるというツールですが、IDEに帯するリモートクライアントという点ではやっていることが似ているので、これは良い統合だったのではないかと思います。
まとめ
さまざまな開発環境が移り変わっていく中で、自分の慣れたIDEをあらゆる環境で使えるというニーズを満たせるJetBrains Gateway(及びProjector)はユースケースが合うのであれば良い選択肢でしょう。
具体的にはシンクライアントなどを使っていて開発環境がリモートサーバー上にあるケースでは非常に刺さるのではないかと思います。
これまでRubyMineのRemote DevelopmentでSCPによるファイル同期(ちょうつらい)やSSHコマンドだけを転送するような使い方をされていた人は、ぜひ一度使ってみてはいかがでしょうか。
Betaが取れた頃に有料になるのかが気がかりではありますが、RubyMineのライセンスは買っているのでGatewayは無料で使わせてもらえると嬉しいなと思っています(個人的にはUltimateユーザーなのでいいのですが、別料金だと人に勧めにくいので)。
ではでは。