62
54

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

docker環境のrails5をstep実行でdebugする

Last updated at Posted at 2016-04-21

docker環境のrails5をstep実行でdebugする

概要

先日 dockerでrails5環境構築で開発環境を作りました。
で、やはり開発する上ではguiでstep実行できると楽だなと思い、

Visual Studio Codeを使ってRailsをデバッグ実行してみよう 

の記事を見つけたのでdocker-machine上で実行されているrailsに対して試してみようとしたところ、先日に引き続きハマり倒したのでその作業メモです。

目標のデバッグ環境

構築した dockerでrails5環境構築の環境は下記のような構成で動いています。

fig-01.png
この環境でホストOS(osx)で実行しているVisual Studio Codeのデバッガでステップ実行したいわけです。

以下先日の「dockerでrails5環境構築」の状態からの変更点を記載していきます。

railsコンテナの設定

基本的には「Visual Studio Codeを使ってRailsをデバッグ実行してみよう」の通りに進めていきます。

  • Gemの追加

    ruby-debug-idedebasedevelopment環境に追加します。

    app/Gemfile
    group :development do
      # 〜略〜
    
      gem 'ruby-debug-ide'
      gem 'debase'
    end
    
  • rdebug-ideでrailsを起動するために起動スクリプト修正

    コンテナ起動時に環境変数DEBUG_MODEを渡すことでデバッグモードでrailsが起動できるように変更します。

    app/bin/run-docker-compose.sh
    #!/bin/sh
    
    SCRIPT_DIR=$(cd $(dirname $0) && pwd)
    
    export DB_DOCKERFILE_DIR=${SCRIPT_DIR}/../db
    export WEB_DOCKERFILE_DIR=${SCRIPT_DIR}/../web
    export WEB_APP_ROOT_DIR=${SCRIPT_DIR}/../../app
    
    export MYSQL_DATABASE=mydb
    export MYSQL_USER=dbuser
    export MYSQL_PASSWORD=dbuser_pass
    export MYSQL_ROOT_PASSWORD=root
    
    export START_RAILS_COMMAND="bundle install --path=vendor/bundle && rm tmp/pids/server.pid;"
    
    # debugモードに切り替える設定
    if [ "$DEBUG_MODE" = "1" ] ; then
      # debug mode
      START_RAILS_COMMAND="${START_RAILS_COMMAND} bundle exec rdebug-ide --host 0.0.0.0 --port 1234 --dispatcher-port 26162 -- bin/rails s -b 0.0.0.0"
    else
      # normal mode
      START_RAILS_COMMAND="${START_RAILS_COMMAND} bin/rails s -b 0.0.0.0"
    fi
    YML_FILE=$SCRIPT_DIR/docker-compose.yml
    
    docker-compose -f $YML_FILE $*    
    

    起動コマンドcommandを直書きしていた部分を↑で設定したSTART_RAILS_COMMANDで置き換えます。
    またrdebug-ideが使うポートをportsに追加します。

    app/bin/docker-compose.yml
    db:
      container_name: db
      build: ${DB_DOCKERFILE_DIR}
      ports:
        - "3306:3306"
      environment:
        MYSQL_DATABASE: ${MYSQL_DATABASE}
        MYSQL_USER: ${MYSQL_USER}
        MYSQL_PASSWORD: ${MYSQL_PASSWORD}
        MYSQL_ROOT_PASSWORD: ${MYSQL_ROOT_PASSWORD}
    
    web:
      container_name: web
      build: ${WEB_DOCKERFILE_DIR}
      ports:
        - "3000:3000"
        - "1234:1234"
        - "26162:26162"
      links:
        - db:db
      volumes:
        - ${WEB_APP_ROOT_DIR}:/var/myapp
      environment:
        DATABASE_NAME: ${MYSQL_DATABASE}
        DATABASE_USER: ${MYSQL_USER}
        DATABASE_PASS: ${MYSQL_PASSWORD}
        DATABASE_HOST: db
      command: sh -c "${START_RAILS_COMMAND}"
    
    • railsコンテナのDockerfileEXPOSEにも1234, 26162を追加します。
    〜略〜
    EXPOSE 3000 1234 26162
    〜略〜    
    

    これでデバッグモードで起動出来るようになったので、buildしなおしてから起動確認します。
    下記のようにFast Debuggerの表示になってwait状態になれば起動成功です。
    (この状態ではまだrailsは起動されていないのでブラウザでアクセスしても何も表示されません。)

    # Dockerfileを直したので再ビルド
    docker/bin/run-docker-compose.sh build
    
    # DEBUG_MODEを指定して起動スクリプトを実行
    DEBUG_MODE=1 docker/bin/run-docker-compose.sh up
    〜略〜
    web    | Fast Debugger (ruby-debug-ide 0.6.0, debase 0.2.1, file filtering is supported) listens on 0.0.0.0:1234
    

Visual Studio Codeの設定

Ruby用の拡張機能のインストールについては

Visual Studio Codeを使ってRailsをデバッグ実行してみよう

を参考にしてください。

この記事にならってデバッグ用の設定ファイルを作成します。

ただし今回はrailsdockerで動いているのでremoteHostの設定をdocker-machineのipに変更し、remoteWorkspaceRootをコンテナ内でデプロイしているパス(ここでは/var/myapp)に変更しておきます。

app/.vscode/launch.json
{
"version": "0.2.0",
"configurations": [
 {
   "name": "Listen for rdebug-ide",
   "type": "Ruby",
   "request": "attach",
   "cwd": "${workspaceRoot}",
   "remoteHost": "192.168.99.100",
   "remotePort": "1234",
   "remoteWorkspaceRoot": "/var/myapp",
   "useBundler": true
 }
]
}

これでVisual Studio Code側の設定も終わったので、先日作ったhello_controller.rbにブレイクポイントを設定してみます。

デバッグ実行

これでrails側もVisual Studio Code側も設定ができたのでデバッグ実行!ということで試してみました。

・・・が、案の定、全くうまく行かず。いくつもハマりどころが合ったので項目毎に解決方法を記載していきます。

  • デバッグサーバが立ち上がらない問題

    先ほどの設定確認ではすんなりrdebugサーバが立ち上がっていましたが、まずここでつまずきました。
    元々遅いと思っていたのですが、このデバッグサーバに関しては耐え切れないほど起動が遅くてとても使ってられませんでした。

    原因はホスト側でソースを編集できるようにVOLUMEappフォルダ以下をマウントしていたのが原因のようでした。
    Virtual Boxの共有フォルダはすこぶる遅いらしく普通の方法ではどうしようもないようです。

    そこでいろいろ調べたところ、

    docker-machine-nfsでOSXのディレクトリをマウントする

    の記事を見つけました。Virtul Boxの共有フォルダをnfsでマウント出来るようにしてくれるツールだそうです。
    開発元のサイトを見てみるとHomebrewでインストールもできて、引数無しで実行した場合はdocker-machineで通常行われる/User以下を(macの場合)設定してくれるそうなので、簡単に導入できました。

    https://github.com/adlogix/docker-machine-nfs

    brew install docker-machine-nfs
    

    でインストールし、docker-machineが起動されている状態で、そのdocker-machine名(ここではdefault)を引数に実行するだけのようです。

    docker-machine-nfs default
    〜略〜                                                                                                                │~                                            |+  16 # debugモー»
    --------------------------------------------                                                                                                                │~                                            |+  17 if [ "$DEBU»
                                                                                                                                                                │~                                            |+  18   # debug m»
     The docker-machine 'default'                                                                                                                               │~                                            |+  19   START_RAI»
     is now mounted with NFS!                                                                                                                                   │~                                            |+  20 else↲
                                                                                                                                                                │~                                            |+  21   # normal »
     ENJOY high speed mounts :D                                                                                                                                 │~                                            |+  22   START_RAI»
                                                                                                                                                                │~                                            |+  23 fi↲
    --------------------------------------------    
    

    途中sudoを使っているようでパスワードを求められたのでパスワード入力し、上記のような表示になればOKです。
    なんとも頼もしいメッセージです。
    で、結果はというと、とんでもなくデバッグサーバの起動が早くなりました。というかすべてが早くなりました。感謝。

  • 途中でステップ実行がふんずまる問題

    これでデバッグサーバがまともに動くようになったのでデバッグしてみます。

    # debugサーバ実行
    DEBUG_MODE=1 docker/bin/run-docker-compose.sh up
    〜略〜
    web    | Fast Debugger (ruby-debug-ide 0.6.0, debase 0.2.1, file filtering is supported) listens on 0.0.0.0:1234
    

デバッグ準備OKなので、Visual Studio Code側からアタッチします。
先ほど作ったデバッグ設定を選択して起動します。

スクリーンショット 2016-04-21 23.16.20.png

すると、railsのコンソール側でpumaが起動します。

    web    | => Booting Puma
    web    | => Rails 5.0.0.beta3 application starting in development on http://0.0.0.0:3000
    web    | => Run `rails server -h` for more startup options
    web    | => Ctrl-C to shutdown server
    web    | Puma starting in single mode...
    web    | * Version 3.4.0 (ruby 2.3.0-p0), codename: Owl Bowl Brawl
    web    | * Min threads: 5, max threads: 5
    web    | * Environment: development
    web    | * Listening on tcp://0.0.0.0:3000
    web    | Use Ctrl-C to stop

この状態で、http://192.168.99.100:3000/hello にアクセスします。

するとバッチリhello_controller.rbに仕掛けたブレイクポイントで止まります・・・・・止まりますが、そのままステップ実行していくと、どうしても途中でステップ実行が止まります。しかもページもずっとロード中のままぐるぐる回り続けます。。

全く止まらないとかエラーになるとかならまだ分かるんですが、途中までステップ実行出来るだけにこれにはハマりまくりました。

で、いろいろ考えたところ、だいたいローカルホストでうまくいくのに、docker-machineでうまくいかない時の定番はネットワーク問題なので、それならlocalhostと通信している体にしてやろう!ということで、ポートフォワーディングで、ローカルの1234, 26162docker-machineの同ポートを繋いでやることにしました。(コンテナとdocker-machineの同ポートは本来のdockerの機能でフォワードされています。)

要は下記のような感じです。(以下のVSCVisual Studio Codeのこと)

もともと
    VSC ----> docker-machineのポート1234 ----> railsコンテナのポート1234
という経路でデバッグサーバにアクセスしていたところを
    VSC ----> localhostのポート1234 ----> docker-machineのポート1234 ----> railsコンテナのポート1234

と、ローカルの1234ポート経由でアクセスしようということです。

ということで、VisualStudioCodeのデバッグ設定を変更します。
下記のようにremoteHostlocalhostにします。

app/.vscode/launch.json
{
  "version": "0.2.0",
  "configurations": [
    {
      "name": "Listen for rdebug-ide",
      "type": "Ruby",
      "request": "attach",
      "cwd": "${workspaceRoot}",
      "remoteHost": "localhost",
      "remotePort": "1234",
      "remoteWorkspaceRoot": "/var/myapp",
      "useBundler": true
    }
  ]
}

次に、ローカルのポートをdocker-machineのポートに繋ぎます。
docker-machinesshコマンドにはその後の引数にsshコマンドのポートフォーワードの書式をそのまま書けるのでそれを利用します。

フォワードするだけなので、適当にターミナルを起動して下記コマンドでdocker-machineにログインしたらそのままほったらかします。

docker-machine ssh default -L 1234:localhost:1234 -L 26162:localhost:26162

この状態で、再度デバッグサーバを立ち上げて、デバッグしてみるとバッチリステップ実行できました。

  • デバッグコンソールで変数を参照すると時々止まる問題

  これは未だ原因不明なのですが、ステップ実行中にVisual Studio Codeのデバッグコンソールで変数をinspectするとコンソールに内容が表示できて便利なのですが、これを行うとタイミングによって(?)デバッグセッションが止まってしまいます。。とりあえず左側のペインで変数の内容とコールスタックが確認できるので致命的に困るようなことでもないため放置です。どなたか解決方法ご存知でしたら教えて下さい。

  • 絶対間違ってない箇所で謎の引数違うよエラーが出る問題

    これは今回の記事用に作ったリポジトリで起きなかったので微妙なのですが、byebuggemと一緒にruby-debug-idegemを使うと変なエラーが出ることがあるそうです。実際別のプロジェクトで試していた時にpry-byebugを同時に使っていたのですが、ブレイクポイントの箇所のコードで明らかに問題ない処理がエラーになって落ちてしまっていました。

RubyMineでdebugできない

http://stackoverflow.com/questions/31046586/cant-debug-rails-app-in-rubymine

を参照しました。

ここまでの内容を反映したのを
https://github.com/pocari/rails5-docker-sample/tree/ver02-enable-remote-debug
にあげています。

62
54
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
62
54

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?