devContainerでDockerかつforemanなrailsプロジェクトをdebugする

2022/10/10

Docker
Rails
VSCode

みなさんはrailsプロジェクトのdebugには何を使用していますか?

昔は、pry-rails がスタンダードだった印象がありますが、Rails7になってdebug gemが入った状態でプロジェクトが作成されるようになったこともあり、debug gemを使ってみたい!という方も増えたのではないでしょうか。

https://github.com/ruby/debug

debug gemについてはクックパッド開発者ブログにて作成者の方の記事が出ているので一読することをお勧めします。

https://techlife.cookpad.com/entry/2021/12/27/202133

また、上記の記事にあるようにVSCodeのdebuggerも使用できるExtentionも作成されており、非常に便利そうなので今回はこちらを利用してVSCodeでデバッグできるようにしてみたので、その紹介です。

(そもそもDockerは使用していたのですが、devContainerを使用したことがなかったり、foremanで複数プロセスを走らせるような仕組みになっていたこともあり、結構詰まった感がありました…)

前提条件

今回使用しているのは以下の環境です。

Rails7の恩恵をマックスに受けてみたい!という意志の強いリポジトリになっていますw

Ruby: 3.1.2
Rails: 7.0.3

`tailwindcss-rails`, `importmap-rails`を使用している

今回のリポジトリはこちらにあります。

iroriの爆速開発をサポートする、app_baseというRailsに個人的に好きな環境を詰め込んだリポジトリです。

https://github.com/irori-dev/app_base

dipでdocker composeを使わなくてもいいようにしていたりするのですが、それはまた別の機会に紹介しますね。

上記のように、tailwindcss-railsを使用している関係上、foremanで複数プロセスを走らせる必要があります。

そのため、docker-compose.ymlで実行されるコマンドは以下のようにbin/devとなっており、以下のProcfile.devを呼び出します。

docker-compose.yml
version: '3.8'

x-app: &x-app
  build:
    context: .
  volumes:
    - .:/app

services:
  app:
    <<: *x-app
    command: ./bin/dev # ここだよ
    ports:
      - "3000:3000"
    depends_on:
      - db
      - redis
      - sidekiq
      - chrome
    tty: true
    stdin_open: true
    environment:
      SELENIUM_DRIVER_URL: http://chrome:4444/wd/hub
      REDIS_URL: redis://redis:6379

  sidekiq:
    <<: *x-app
    environment:
      REDISTOGO_URL: redis://redis:6379
      REDIS_PROVIDER: REDISTOGO_URL
    command: ["./bin/bundle", "exec", "sidekiq", "-C", "config/sidekiq.yml"]
    ports: []
    depends_on:
      - db
      - redis

  redis:
    image: redis:6.0-alpine
    command: ["redis-server"]
    ports:
      - "6379:6379"
    volumes:
      - redis-data:/data

  db:
    image: postgres
    environment:
      POSTGRES_USER: postgres
      POSTGRES_PASSWORD: password
    ports:
      - "4432:5432"
    volumes:
      - postgres_volume:/var/lib/postgresql/data
    restart: always

  chrome:
    image: seleniarm/standalone-chromium
    shm_size: 2g
    ports:
      - "4444:4444"
volumes:
  postgres_volume:
  redis-data:
Procfile.dev
web: rm -f tmp/pids/server.pid && bin/rails server -p 3000 -b '0.0.0.0'
css: bin/rails tailwindcss:watch

今回はこの状態をrdbgで置き換えて、devContainer内でのdebugを簡単にしてみます!

devContainerやっていき

そもそもdevContainerとは

devContainerとは、VSCodeの純正の拡張機能でDockerなどのリモート環境を立ち上げ、実行ができる機能です。

既存のdocker-compose.ymlなどをベースに作成できるので、簡単にVSCodeの恩恵をコンテナ管理のプロジェクトでも受けることができるようになります。

https://code.visualstudio.com/docs/remote/containers

devContainerが開けるようにする

まずはdevContainerが開ける準備をします。

といっても、以下のファイルを作成するだけです。

.devcontainer/devcontainer.json
{
  "dockerComposeFile": ["../docker-compose.yml"],
  "service": "app",
  "workspaceFolder": "/app",
}

これを作成したら、右下の><みたいなマークからReopen in Containerを選択しましょう。

1.png

2.png

無事に開けたら、http://localhost:3000を見てみましょう。

起動できていたら、devContainer環境の作成には成功しています。

debug gemでdebugできるようにする

さて、いよいよdevContainerで立ち上げられるようになったところでdebugできるようにしていきます。

先ほど作成した、.devcontainer/devcontainer.jsonに以下のように追記します。

.devcontainer/devcontainer.json
{
  "dockerComposeFile": ["../docker-compose.yml"],
  "service": "app",
  "workspaceFolder": "/app",
  "extensions": [ // ここから
    "KoichiSasada.vscode-rdbg"
  ] // ここまで
}

そして、新たに.vscode/launch.jsonを作成します。

.vscode/launch.json
{
  "version": "0.2.0",
  "configurations": [
    {
      "type": "rdbg",
      "name": "Attach with rdbg",
      "request": "attach",
    }
  ]
}

最後に、bin/devで実行されるコマンドを修正します。

Procfile.dev
web: rdbg --open=vscode --nonstop -c -- bin/rails s -p 3000 -b '0.0.0.0'
css: bin/rails tailwindcss:watch

ここまで変更したら、再度Reopen in Containerしてみましょう。

devContainerはVSCodeの該当ウィンドウを閉じると自動でコンテナもdownしてくれます。便利ですね。

無事起動できたら、左のRun and Debugタブを選択し、Attach with rdbgが選択されていることを確認してから緑の三角ボタンを押して実行します。

3.png

実行できたら、例えばroot_pathのコントローラを開いて、赤の丸をつけてみましょう。

4.png

その後、root_pathにアクセスするとリクエストが途中で止まり、以下のようにデバッグできる状態になっています!

5.png

下のDEBUG CONSOLEから今の状態を確認できます。次に進めたければこの次へっぽい三角を押せば進みます。

6.png

これで開発体験が爆上がりしたはずです。皆さんも良きRailsライフを!

Related Posts

[Hotwire] turbo_frame_tagで非同期いいねボタンを実装する

[Hotwire] turbo_frame_tagで非同期いいねボタンを実装する

[Rails] view_componentというgemがすごく便利なので紹介します

[Rails] view_componentというgemがすごく便利なので紹介します