ぺのめも

Web開発を勉強中。学んだことや思ったことなど

VSCodeのRemote ContainerでRubyの開発環境を構築する

はじめに

Ruby on RailsWebサービスを個人開発中です。
Docker+VSCode Remote Container開発環境を作るにあたり、初めてで色々調べながら進めたので、記録しておきます。
やってみて分かったのですが、開発環境はDockerコンテナを使いつつ、コーディングはローカルでやるのと全く変わらない感じでVSCode上でできるので、かなり快適です。

そもそもDockerとは?

Docker自体に初めて触れる方の場合は、こちらの記事をさらっと読んでから戻ってくると、この後の内容を読み進めやすいと思います。

peno022.hatenablog.com

手順

VSCodeでコンテナを起動・接続する

プロジェクトディレクトリ自体は、既に作成済みの状態から始めます。
VSCode公式のドキュメントの手順に沿って進めていきました。
code.visualstudio.com

1)Docker Desktopのインストール

  • Windows: Docker Desktop 2.0+ on Windows 10 Pro/Enterprise. Windows 10 Home (2004+) requires Docker Desktop 2.3+ and the WSL 2 back-end. (Docker Toolbox is not supported. Windows container images are not supported.)
  • macOS: Docker Desktop 2.0+.
  • Linux: Docker CE/EE 18.06+ and Docker Compose 1.21+. (The Ubuntu snap package is not supported.)
  • Remote hosts: 1 GB RAM is required, but at least 2 GB RAM and a 2-core CPU is recommended.

私の場合はMacを利用しているので、Mac版のDocker Desktopを利用しています。
Docker Desktopのインストール自体は過去に行っていたので(ほとんど使わないままでしたが)、今回はアプリを最新バージョンにアップデートすることだけ実施しました。

2)VSCodeを起動し、対象ディレクトリとコンテナの設定方法を選択する

VSCodeを起動し、開発対象のプロジェクトのフォルダを開きます。
VSCodeのコマンドパレットを開き(Macであれば command + Shift + p)「Dev Containers: Open Folder in Container...」を選択します。
ディレクトリ選択画面が開くので、コンテナ上で開発したいプロジェクトのディレクトリを選択すればOKです。
ディレクトリを選択すると、コンテナ設定の方法を選択する画面になります。

  • From a predefined container configuration definition...
    →既存のテンプレートから選択する形式です。
  • From 'Dockerfile'
    →プロジェクトディレクトリに既にDockerfileもしくはdocker-compose.ymlを作成済みであれば、それを元にコンテナを実行します。

コンテナの設定方法を選択する
コンテナの設定方法を選択する

今回はまだDockerfileを何も作っていなかったので、「From a predefined container configuration definition...」のほうを選択しました。

3)ベースとなるテンプレートを選択する

ベースとなるテンプレートを選択する画面になります。
今回は「Ruby on Rails & Postgres」を選択しました。
ちなみに「i」のアイコンをクリックすると、そのテンプレートのリポジトリがブラウザで開きます。

ベースにするDockerイメージを選択する
ベースにするDockerイメージを選択する

次に、Rubyバージョンを選択します。
今回は「3.1」を選択しました。

Rubyのバージョンを選択する
Rubyのバージョンを選択する

さらに追加でインストールしたいものがあれば、選択します。
今回は何も選択せず、「OK」だけ押下。

追加でインストールしたいものを選択
追加でインストールしたいものを選択

4)プロジェクトがコンテナ上で開く

ここまでの設定を終えると、コンテナの構築が始まり、VSCodeが再読み込みされました。簡単!

VSCodeがコンテナを起動・読み込み
VSCodeがコンテナを起動・読み込み

ローカルでプロジェクトを開いていた時のVSCodeの見え方と違うのは、

  • ウィンドウの左下にDev Containerの表示が出ていること
  • ターミナルでコンテナ内のシェルが動くようになっていること

です。

ウィンドウの左下にDev Containerの表示が出ている
ウィンドウの左下にDev Containerの表示が出ている

この時点で、.devcontainerディレクトリ配下にこれらのファイルが自動作成されています。

  • create-db-user.sql
  • devcontainer.json
  • docker-compose.yml
  • Dockerfile

作成されたDockerfileの内容:

FROM mcr.microsoft.com/devcontainers/ruby:0-3.1

# Install Rails
RUN gem install rails webdrivers

# Default value to allow debug server to serve content over GitHub Codespace's port forwarding service
# The value is a comma-separated list of allowed domains 
ENV RAILS_DEVELOPMENT_HOSTS=".githubpreview.dev,.preview.app.github.dev,.app.github.dev"

# [Optional] Uncomment this section to install additional OS packages.
# RUN apt-get update && export DEBIAN_FRONTEND=noninteractive \
#     && apt-get -y install --no-install-recommends <your-package-list-here>

# [Optional] Uncomment this line to install additional gems.
# RUN gem install <your-gem-names-here>

# [Optional] Uncomment this line to install global node packages.
# RUN su vscode -c "source /usr/local/share/nvm/nvm.sh && npm install -g <your-package-here>" 2>&1

Dockerfileを編集する(必要に応じて)

土台のDockerイメージを変更

Rubyのバージョンが細かく指定できなさそうだったのと、既にnvmインストール済みだったりしてコンテナの中身が分かりづらかったので、土台のDockerイメージをmcr.microsoft.com/devcontainers/ruby:0-3.1ではなく、Docker Hubのofficial imageのrubyに変更しました。

# FROM mcr.microsoft.com/devcontainers/ruby:0-3.1 を書き換え
FROM ruby:3.1.3

hub.docker.com

nvm、nodeをインストール

nvmの公式で記載されているインストール方法はbashで実行するのが前提です。

# 公式に記載のインストールコマンド
curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.3/install.sh | bash


しかし、今回利用するDockerイメージのデフォルトのshellはshだったので、bashを実行するために

SHELL ["/bin/bash", “-c”]

をDockerfileに追記したうえでbashコマンドを書く必要がありました。
一時的にbashを使う場合はRUN ["/bin/bash", "-c", "echo hello”]とも書けるみたいですが、基本bashでよいので、こちらにしておきました。
参考: qiita.com
更新後のDockerfile:

FROM ruby:3.1.3
SHELL ["/bin/bash", "-c"]

# Install Rails
RUN gem install rails webdrivers

# Default value to allow debug server to serve content over GitHub Codespace's port forwarding service
# The value is a comma-separated list of allowed domains
ENV RAILS_DEVELOPMENT_HOSTS=".githubpreview.dev,.preview.app.github.dev,.app.github.dev"

# [Optional] Uncomment this section to install additional OS packages.
# RUN apt-get update && export DEBIAN_FRONTEND=noninteractive \
#     && apt-get -y install --no-install-recommends <your-package-list-here>

# [Optional] Uncomment this line to install additional gems.
# RUN gem install <your-gem-names-here>

RUN curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.3/install.sh | bash \
  && source ~/.bashrc \
  && nvm install 19.4 \
  && nvm use 19.4

再ビルド

Dockerfileを更新したら、VSCodeのコマンドパレットから「Rebuild Container」を実行するだけで、再ビルド・再読み込みされます。簡単で助かりますね。

デバッグする時

ただ、VSCodeの「Rebuild Container」でビルドすると、エラーが出た時にログが見られず原因がよく分かりませんでした。
なので、下記のような手順を取るとやりやすかったです。
(前節に書いた、今回の状況だとデフォルトshellがbashではないということを知らずビルドに失敗したりしました)

  1. いったんローカルの適当な場所にDockerfileをコピー
  2. docker build -t tmp-image .のコマンドを実行してビルド(※)
  3. エラーが出たらログを見て適宜Dockerfileを修正
  4. ビルドに成功することを確認してから、そのDockerfileの内容を.devcontainer配下の本体のDockerfileに反映し、以降はVSCodeの「Rebuild Container」を利用

※Dockerビルドコマンドの補足

  • -tはタグ名をつけるオプション
  • tmp-imageの部分は任意の名前でOK
  • .の部分はコピーしたDockerfileが置いてあるディレクトリへの相対パス