binding.pryが効かない

Share this post

環境

ruby:2.5.3
rail:5.2.2
Docker:3
Mysql:5.7

現象

Docker,rails環境を使用し開発を進め、変数の値がどうなっているかを確認するため

  • gem 'pry-rails'
  • gem 'pry-byebug'

をインストール後、
binding.pryを仕掛けたが
仕掛けたところで止まってくれなかった。

##失敗環境

Docker-compose.yml ↓↓

version: '3'
services:
  db:
    image: mysql:5.7
    environment:
      MYSQL_ROOT_PASSWORD: password
      MYSQL_DATABASE: root
    ports:
      - "5500:3306"

  web:
    build: .
    command: /bin/sh -c "rm -f tmp/pids/server.pid && bundle exec rails s -p 3000 -b 0.0.0.0"
    volumes:
      - .:/app_name
    ports:
      - "5000:3000"
    links:
      - db

止めたかった場所 ↓↓

#コントローラー 
class FrontController < ApplicationController
  layout false
  require "open-uri"
  require "nokogiri"
  def index

    binding.pry  #ここで止めたい!!!!!!!!!!!

    url = "https://www.sejuku.net/blog/"
    charset = nil
    html = URI.open(url) do |page|
      charset = page.charset
      page.read
      @contents = Nokogiri::HTML.parse(html,nil,charset)
    end
  end
end

ブラウザ更新後のターミナル ↓↓


From: /app_name/app/controllers/front_controller.rb:10 FrontController#index:

     5: def index
     6: 
     7:   binding.pry
     8:   
     9:   #クレイピング対象のURL
 => 10:   url = "https://dummy"
    11:   #取得するhtml用charset
    12:   charset = nil
    13:   
    14:   html = URI.open(url) do |page|
    15:     #charsetを自動で読み込み、取得
    16:     charset = page.charset
    17:     #中身を読む
    18:     page.read
    19:     @contents = Nokogiri::HTML.parse(html,nil,charset)
    20:   end
    21: end

[1] pry(#<FrontController>)>   Rendering front/index.html.erb
  Rendered front/index.html.erb (0.5ms)
Completed 200 OK in 241ms (Views: 19.5ms | ActiveRecord: 0.0ms)

処理を止めて色々試したいが勝手にbinding.pryを仕掛けている場所を通過してしまう。
上記のような状態で意外と詰まってしまったためメモ。

解決策

Docker-compose.ymlに

tty: true
stdin_open: true

のどちらか片方でも追加するとちゃんと止まってくれた。(なぜ...?理由は後で)

docker-compose.yml ↓↓

#docker-compose.yml
version: '3'
services:
  db:
    image: mysql:5.7
    environment:
      MYSQL_ROOT_PASSWORD: password
      MYSQL_DATABASE: root
    ports:
      - "5500:3306"

  web:
    build: .
    command: /bin/sh -c "rm -f tmp/pids/server.pid && bundle exec rails s -p 3000 -b 0.0.0.0"
    volumes:
      - .:/app_name
    ports:
      - "5000:3000"
    links:
      - db
    tty: true         #ここ!!!!!
    stdin_open: true  #ここ!!!!!

ブラウザ更新後のターミナル ↓↓

#ターミナル
From: /app_name/app/controllers/front_controller.rb:10 FrontController#index:

     5: def index
     6: 
     7:   binding.pry
     8:   
     9:   #クレイピング対象のURL
 => 10:   url = "https://dummy"
    11:   #取得するhtml用charset
    12:   charset = nil
    13:   
    14:   html = URI.open(url) do |page|
    15:     #charsetを自動で読み込み、取得
    16:     charset = page.charset
    17:     #中身を読む
    18:     page.read
    19:     @contents = Nokogiri::HTML.parse(html,nil,charset)
    20:   end
    21: end

[1] pry(#<FrontController>)> 

これで一応解決。

「tty:」  と 「stdin_open:」  って何?

参考記事
【Rails】Docker環境下でbinding.pryを使えないとき確認すべきポイント4つ

stdin_open:

標準入出力とエラー出力をコンテナに結びつける設定コマンド。

tty:

擬似端末(キーボードによる入力)をコンテナに結びつける設定コマンド。
これにより「コンテナを起動させ続けること」ができるようになる。

推測

上記が抜けているとホストPCからDockerコンテナに対して入力するための術がないために
勝手に(自動で)「Exit」のような処理がなされていた?ということ?

詳しい事はわからなかっため、分かる方がいらっしゃったらコメントを頂ければ嬉しいです。
以上です!

Share this post

Newt Made in Newt