Rails 7でリモートデバッグする方法(翻訳)
本記事は、私の著書『The Rails and Hotwire Codex』から抜粋して手を加えたものです。
Rails 7にはRuby公式のruby/debugが含まれています。また、開発中に複数プロセスをオーケストレーションするためにForemanも使われています。Foremanによって、Railsサーバーを起動するコマンドを実行するだけで、フロントエンドのアセットを監視・コンパイルする他のプロセスも一緒に起動されるようになります。
しかし困ったことに、これによってデバッグが面倒になります。アプリにブレークポイントを追加して、コンソールでコマンドを実行することができなくなります。同じターミナルウィンドウで複数のプロセスが実行されているため、プロセスに対する対話的操作が常に可能とは限らなくなります。
Rubyのdebug
gemは、こういう場合に便利なリモートデバッグをサポートしています。これをセットアップしておけば、外部の独立したデバッガプロセスを、デバッグ対象となる別のRubyプロセス(すなわち"debuggee")にアタッチできるようになります。
Railsアプリでリモートデバッグを有効にするには、application.rbに以下の行を追加します。
require "rails/all"
if defined?(Rails::Server) && Rails.env.development?
require "debug/open_nonstop"
end
# ...
この設定では、リモートデバッグを有効する前に、Railsがdevelopment環境であることと、Rails::Server
定数が定義済みであることを検証しています。後者のチェックにより、アプリがWebサーバーのコンテキストで実行されている場合にのみリモートデバッグが有効になります。バックグラウンドジョブ(RailsコンソールやSidekiqなど)の他のコンテキストではデバッガを有効にすべきではありません。
これで、development環境のRailsサーバーを起動すると、debug
gemがUnixドメインソケットを開いて、そこにデバッガプロセスを接続可能になります。
bin/dev
でRailsサーバーを起動したら、別のターミナルウィンドウで以下を実行します。
$ bundle exec rdbg -a
現在実行中のデバッグ可能なプロセスがRailsサーバーだけである場合(そうでないと困ります)、デバッガが接続されます。これで、アプリにブレークポイントを追加したり、デバッガプロセスでコマンドを実行したりできます。
Ctrl+D
キーを押すとデバッガが終了します(Railsサーバーは実行中のままになります)。デバッグが終わったらCtrl+D
キーで終了することをおすすめします。デバッガで使えるコマンドの全リストについてはドキュメントを参照してください。
注: require "debug/open_nonstop"
の代わりにrequire "debug/open"
というステートメントも使えます。ただし、この場合はデバッガをアタッチすると、continue
コマンドを実行するするまでプログラムが一時停止するという欠点があります。開発中にサーバーを何度も再起動することを考えると、これは非常に面倒になる可能性があります。
お知らせ
本記事を気に入っていただけたら、ぜひ私の著書『The Rails and Hotwire Codex』を読んでRailsとHotwireのスキルをアップしてください。
概要
原著者の許諾を得て翻訳・公開いたします。
参考: Rails アプリケーションのデバッグ - Railsガイド