さめたコーヒー

kbaba1001's blog.

VS Code - Remote Containers で Docker Compose で動いている Rails アプリに接続する

VS Code に Remote という機能が作られつつある。これは VS Code から Docker や WSL や外部サーバーなどの環境に接続して、あたかもその環境の中で VS Code を立ち上げているかのように開発ができるというもの。

詳しくは下記を参照

code.visualstudio.com

単にDockerfileで環境を用意するだけならいくつか公式のサンプルがある。(Rubyはないけど)

git clone https://github.com/Microsoft/vscode-remote-try-node
git clone https://github.com/Microsoft/vscode-remote-try-python
git clone https://github.com/Microsoft/vscode-remote-try-go
git clone https://github.com/Microsoft/vscode-remote-try-java
git clone https://github.com/Microsoft/vscode-remote-try-dotnetcore
git clone https://github.com/Microsoft/vscode-remote-try-php
git clone https://github.com/Microsoft/vscode-remote-try-rust
git clone https://github.com/Microsoft/vscode-remote-try-cpp

ただ仕事で使っているプロジェクトは docker-compose で環境を作っているので、それをそのまま使いたい。

Docker Compose の service に VS Code remote で接続する

Rails を Docker Compose で動かす方法については次などを参考にしてほしい。

docs.docker.com

上記相当のアプリがある前提で以下を進める。

環境として次がインストール済みであるとする。

  • VS Code バージョン 1.35 以上 または VS Code insiders
  • Remote - Containers

VS Code Remote - Containers を使うためにリポジトリに次のファイルを用意する。

.devcontainer/devcontainer.json

{
  "name": "My Project",                                // 適当に名前をつける
  "dockerComposeFile": [
    "../docker-compose.yml",
    "docker-compose.extend.yml"
  ],
  "service": "web",                                         // docker-compose.yml 中の web という service を使う想定
  "workspaceFolder": "/myapp",
  "extensions": [
    "rebornix.ruby"                                         // remote 中に使いたいエクステンションを指定できる
  ],
  "settings": {
    "editor.tabSize": 2,
    "files.insertFinalNewline": true,
    "files.trimFinalNewlines": true,
    "terminal.integrated.shell.linux": "/bin/bash"
  },
  "shutdownAction": "stopCompose"
}

.devcontainer/docker-compose.extend.yml

version: "3"
services:
  web:
    volumes:
      - ~/.gitconfig:/root/.gitconfig
    command: sleep infinity                           // 後述

.devcontainer 以下に Remote - Containers 用の設定を置く。 .devcontainer/devcontainer.json に使える設定値は下記を参照。

code.visualstudio.com

面白いことに dockerComposeFile では docker-compose.yml を複数指定することができる。 これにより既存の docker-compose.yml を変更することなく、 Remote - Conteiners 用の設定を別ファイルに定義してオーバーライドすることができる。 上記の例ではもともとプロジェクトで使っている docker-compose.yml を .devcontainer/docker-compose.extend.yml で上書きするように設定している。

主に上書きしたいポイントは command の部分。 もともとの docker-compose.yml では command: bundle exec rails s -p 3000 -b '0.0.0.0' のように rails server が起動することを想定している。 このままでもいいのだが、 VS Code のデバッガーを使ったりサーバーをこまめに立ち上げたり落としたりしたいので、あえてこのコマンドを潰しておきたい。 そのため、 command: sleep infinity によりコンテナは起動したままにするが特に具体的なことは行わないようにする。

あとは下記に従って docker の中で VS Code を開くようにする。

marketplace.visualstudio.com

デバッガーを使えるようにする

今までの設定により Ruby 用のプラグインが使える状態になっているはずなので、 debugger を使えるようにしてみる。

marketplace.visualstudio.com

まず、プロジェクトの Gemfile に以下を追加する (Ruby v2.x 系の場合。それ以外は上記リンク先を参照)

group :development, :test do
  gem install ruby-debug-ide
  gem install debase
end

debugger の launch を設定する必要があるので以下の内容で .vscode/launch.json を作成する。

{
  // Use IntelliSense to learn about possible attributes.
  // Hover to view descriptions of existing attributes.
  // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
  "version": "0.2.0",
  "configurations": [
    {
        "name": "Debug Rails server",
        "type": "Ruby",
        "request": "launch",
        "cwd": "${workspaceRoot}",
        "useBundler": true,
        "pathToBundler": "/usr/local/bin/bundle",
        "pathToRDebugIDE": "/bundle/gems/ruby-debug-ide-0.7.0/bin/rdebug-ide",
        "program": "${workspaceRoot}/bin/rails",
        "args": [
            "server",
            "-p", "3000",
            "-b", "0.0.0.0"
        ]
    },
    {
        "name": "Run RSpec - all",
        "type": "Ruby",
        "request": "launch",
        "cwd": "${workspaceRoot}",
        "useBundler": true,
        "pathToBundler": "/usr/local/bin/bundle",
        "pathToRDebugIDE": "/bundle/gems/ruby-debug-ide-0.7.0/bin/rdebug-ide",
        "program": "/bundle/bin/rspec",
        "args": [
            "--format", "documentation"
        ]
    },
    {
        "name": "Debug RSpec - open spec file",
        "type": "Ruby",
        "request": "launch",
        "cwd": "${workspaceRoot}",
        "useBundler": true,
        "pathToBundler": "/usr/local/bin/bundle",
        "pathToRDebugIDE": "/bundle/gems/ruby-debug-ide-0.7.0/bin/rdebug-ide",
        "debuggerPort": "1235",
        "program": "/bundle/bin/rspec",
        "args": [
            "--format", "documentation",
            "${file}"
        ]
    }
  ]
}

参考: vscode-recipes/README.md at 2174a750102a76142378ea08dbbb4a576dc6d1d5 · microsoft/vscode-recipes · GitHub

以上の設定により Debug Rails server でデバッガーのブレイクポイントを有効にしてサーバーを起動できる。 Run RSpec - allDebug RSpec - open spec file ではテストの実行もできる。