VSCodeでDockerを使ったRailsを開発しよう~Dev Containers編~

VSCodeでDockerを使ったRailsを開発しよう~Dev Containers編~

概要

開発者のマシンで開発環境を構築する際にDocker及びDocker composeを使って開発することが一般的になりました。ターミナルからdocker composeコマンドを実行してテストや動作確認するのがセオリーですが、VS CodeのDev Containers拡張を使うことによりVS Codeで便利に開発する方法を提案します。 今回はRailsプロジェクトを使ったDev Containersのセットアップ方法を紹介します。

目次

目的

VS CodeとDockerを使ったRailsをより便利にします(以下 コンテナと記載されている箇所はDockerコンテナ及びDocker Composeで起動したコンテナ群を指す)。

  • SSHでリモートサーバにアクセスするように、コンテナに入った状態のターミナルを動かせるので、 docker compose exec ~~ とDockerのコマンドを打つ必要がなくなり、開発作業を楽にします
  • コンテナで起動するVS Code拡張を指定できるので、RubcopやSolargraphなどの拡張機能をインストール・設定を開発者が個別にする必要がなくなり開発環境を標準化できます

対象読者

VSCodeを使うRailsエンジニアおよび、開発環境を標準化したいリーダー層

PR

UZUMAKIではアジャイル開発で新規事業の開発から、大規模Webアプリケーションのアーキテクチャ更新などの開発をしています。

お問い合わせはUZUMAKIのHPのお問合せフォームから

本文

準備

本記事のサンプルコードは下記URL(vscodeタグ)にあります

前提条件

動作確認した環境は以下のとおりです

  • M2 CPUのMac
  • Docker desktop for mac: 4.16.2
  • Ruby: 3.2.1
  • Rails: 7.0.4
  • MySQL: 8
  • ※ 細かいバージョンはDockerfile、docker-compose.ymlに記載
  • rails new コマンドで適当なRailsプロジェクトを作成し、Post, Commentモデルをscaffoldで作成

Railsを動かすベースのDockerfileを作成します

FROM ruby:3.2.1
ENV ROOT="/app"
ENV LANG=C.UTF-8
ENV TZ=Asia/Tokyo

WORKDIR ${ROOT}

COPY Gemfile ${ROOT}
COPY Gemfile.lock ${ROOT}

RUN gem install bundler
RUN bundle install --jobs 4

ミドルウェアの指定をするdocker-compose.ymlを作ります

version: '3'
services:
  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:cached
      - bundle-volume:/usr/local/bundle
    ports:
      - 3000:3000
    depends_on:
      - db
    tty: true
    stdin_open: true
  db:
    image: mysql:8
    volumes:
      - mysql-volume:/var/lib/mysql
    environment:
      MYSQL_ROOT_PASSWORD: password
      TZ: "Asia/Tokyo"
    ports:
      - "3306:3306"
volumes:
  bundle-volume:
  mysql-volume:
docker compose up

データベースを作成する

docker compose run --rm web rails db:prepare

http://localhost:3000 にアクセスしてトップページが表示されることを確認してください。

リモート用のコンテナの設定をする

VS Code拡張機能 Remote Development をインストール

下記のリンクから追加

下記4つの拡張期の機能のパックなので、今回使用するのはDev Containersのみインストールしても構いません

  • Remote - SSH - Work with source code in any location by opening folders on a remote machine/VM using SSH. Supports x86_64, ARMv7l (AArch32), and ARMv8l (AArch64) glibc-based Linux, Windows 10/Server (1803+), and macOS 10.14+ (Mojave) SSH hosts.
  • Remote - Tunnels - Work with source code in any location by opening folders on a remote machine/VM using a VS Code Tunnel (rather than SSH).
  • Dev Containers - Work with a separate toolchain or container based application by opening any folder mounted into or inside a container.
  • WSL - Get a Linux-powered development experience from the comfort of Windows by opening any folder in the Windows Subsystem for Linux.

この拡張機能を他のメンバーにもインストールを推奨(機能的に強制できません)するように設定ファイルを追記します。

.vscode/extensions.json

{
  "recommendations": [
    "ms-vscode-remote.vscode-remote-extensionpack", // Remote Development
  ]
}

Dev Containers用の設定ファイルを作成します。

.devcontainer/devcontainer.json

{
	"name": "Existing Docker Compose",
	"dockerComposeFile": [ //2つ目のdocker-compose.ymlで1つ目の設定を上書きます
		"../docker-compose.yml",
		"docker-compose.yml"
	],
	"service": "web",//docker-compse.ymlで記載されている起動対象のサービス名、Railsのサービスを指定します
  "workspaceFolder": "/app"//起動時に接続するディレクトリ
}

上書きするdocker-compose.ymlを作成し、起動時のコマンドでRailsが起動しないようにします

.devcontainer/docker-compose.yml

version: '3'
services:
  web:
    # docker起動時にRailsが起動しないようにする
    command: /bin/sh -c "while sleep 1000; do :; done"

VS Codeからコンテナを起動する

VS Codeの左下の緑の部分をクリックまたは、コマンドパレットからRopen in Containerを選択します。

image
image

コンテナ内で使用する拡張機能を指定する

コンテナ内ではコンテナ外でインストールしている拡張機能は使えません。改めてインストールする必要があります。一見この点は不便なのですが、コンテナ内で使用する拡張機能は設定ファイルで指定することができセットアップが簡単になります。

今回は下記を導入します。

  • solargraph
  • rubocop
  • Ruby拡張
  • rdbg ※ デバッグ用

.devcontainer/devcontainer.jsonファイル書きを追記します。

{
  // 中略

  // コンテナ内で使う拡張機能
	"customizations": {
		"vscode": {
			"extensions": [
				"castwide.solargraph", // solargraph
				"rebornix.Ruby", // Rubyのシンタックスハイライトなど
				"misogi.ruby-rubocop", // Rubocop
				"KoichiSasada.vscode-rdbg" // Ruby Debug 後述
			]
		}
	}
}

VS Codeでプロジェクト用の設定をする

プロジェクト専用の設定をします。ここではRubyのインデントをスペース2にします。

.vscode/settings.json

{
    "[ruby]": {
        "editor.tabSize": 2
    }
}

GemfileにSolergraphとRubocop用のgemを追記

拡張機能で利用するgemをインストールするよう指定します。

group :development do
  gem 'solargraph'
  gem 'rubocop', require: false
  gem 'rubocop-rails', require: false
  gem 'rubocop-performance', require: false
end

動作確認

VS Codeからコンテナを起動してRubocpや、Solargraphが動いていることを確認してください。

Rubocop

おなじみのRuby用のLinterはProblemsのパネルから見ることができます。

image

Solargraph

自動補完や、メソッドやクラスの定義へジャンプできる便利なツールです。使っていない方はぜひ導入してみてください。

※ SolargraphとVS Codeの組み合わせはコンテナ外から動かそうとすると設定が煩雑ですがDev Containersを使うと設定が容易です。

image

Dev Containersを使ったRails 開発のリズム

Dev Containersを使って開発することで、Railsのコンテナに入った状態のターミナルが開けるので、まるでDockerを使わないでローカル開発するような感覚で開発ができます。

image

コンテナの外からコンテナ内のRailsに対してコマンドを実行する場合、DockerのコマンドとRailsのコマンドの両方を考慮して考える必要があり若干脳に負荷がかかります。 Docker Composeの起動時にRailsを起動させる設定でコンテナの外からRailsに対するコマンドと、コンテナ内から打つコマンドを比較すると、下記の表のようにコマンドを少なくすることができ便利です。

コンテナの外からRailsに対するコマンド
コンテナ内から打つコマンド
docker compose run --rm web bundle install
bundle install
docker compose run --rm web bin/rails db:migrate
bin/rails db:migrate
docker compose exec web bin/rails c
bin/rails c
docker compose exec web bundle exec rspec
bundle exec rspec
docker compose run -e EDITOR=emacs web bin/rails credentials:edit
bin/rails credentials:edit

またTerminalパネルから、rails serverを起動したりrspecをターミナルから実行することができるのでブレークポイントで止めて動作確認をすることもできます。

image

Tips

コンテナから出たいと思ったら

コマンドパレットから Reopen Folder Locally を実行する

image

設定が反映されないと思ったら

コンテナをリビルドしてみると解決しやすいです。コマンドパレットから下記のどちらかを実行してみると良いでしょう

image

考察

Pros

  • VS Codeの拡張機能を開発メンバーで標準化できる
    • コンテナ内のRubyを使う拡張機能の設定が楽
  • VS Codeのターミナルはコンテナに入った状態で作業でき、Docker(Docker Component)のコマンドを省略して開発できる
  • Railsをdevelopment環境で起動した際にブレークポイントでデバッグするのが楽
    • docker attachコマンドが不要なので、動作確認やバグの調査が楽

Cons

  • VS Code以外のエディタには適用できない
  • Dev Containersの拡張機能が若干クセがある
  • コンテナ内のシェルの設定を普段の開発環境のものが使えない
    • Zshやインクリメンタルサーチを入れるべきか、エイリアスなど

まとめ

VS Codeで開発する際に、Docker及びDocker composeとVS Codeの拡張機能Dev Containersを使う方法を紹介しました。Railsのプロジェクトでの例を紹介しました。

個人的には、Solargraphの設定が楽なのと、 docker attach コマンドを使う必要がないところがお気に入りのポイントです。

参考リンク

PR

XではUZUMAKIの新しい働き方や日常の様子を紹介!ぜひフォローをお願いします!

noteではUZUMAKIのメンバー・クライアントインタビュー、福利厚生を紹介!

UZUMAKIではRailsエンジニアを絶賛募集中です。

↓の記事を読んでご興味を持っていただいた方は、ぜひ応募よろしくお願いします!

是非応募宜しくおねがいします!