🐙

Rails + Next.jsの開発環境をコンテナで用意してVS Codeで開発したい

2023/12/15に公開

VS Codeでwebアプリケーションの開発をしています。
Rails + Nodeの環境をローカルに構築するために色々インストールするのがなんか嫌だなと思ったので、開発環境をひっくるめて一つのコンテナに入れて、その中で開発する方法を調べました。
VS CodeのDev Containers拡張を使うことで、比較的楽に実現できたので、うまくいった方法を整理します。

なお、以下のようなディレクトリ構成を想定しています。

- frontend
- backend
- .devcontainer
  |- devcontainer.json
  |- docker-compose.yml
  |- Dockerfile

今回作る開発環境に必要なのは、backendのためのRuby、frontendのためのNode.js、そしてDBサーバーです。
また、VS CodeにはあらかじめDev Containers拡張をインストールしておきます。
https://marketplace.visualstudio.com/items?itemName=ms-vscode-remote.remote-containers

.devcontainer下のファイル

今回拡張性を考え、docker-composeとDockerfileを利用する方法を採りました(やろうと思えばこれらがなくても設定できるみたいです)。
各ファイルの中身は以下の通りです。

/.devcontainer/Dockerfile
FROM mcr.microsoft.com/devcontainers/ruby

WORKDIR /workspace/frontend

COPY frontend/package.json ./
COPY frontend/yarn.lock ./

RUN bash -c "source /usr/local/share/nvm/nvm.sh && nvm install stable && nvm alias default stable"

RUN yarn install

devcontainers用のimageは多数公開されており、そのうちRubyが入ったイメージにnvmも同梱されているようだったので、こちらを選びました。gitなども入っています。
ただしDockerfile内でnvmコマンドを実行するにはPATHが通っていないため、source /usr/local/share/nvm/nvm.shを差し込む必要がありました。

現状まだbackendの実装を用意していないのでとりあえずfrontendの依存関係のインストールだけ行なっています。実際には同様にbackend側のインストールも必要なはずですが、ここまででも動作確認は可能です。

/.devcontainer/docker-compose.yml
version: "3.8"
services:
  app:
    container_name: app
    build:
      context: ../
      dockerfile: .devcontainer/Dockerfile

    volumes:
      - ..:/workspace
      - node-modules:/workspace/frontend/node_modules

    command: sleep infinity

  db:
    container_name: db
    image: postgres:latest
    volumes:
      - postgres-data:/var/lib/postgresql/data
    environment:
      POSTGRES_PASSWORD: postgres
      POSTGRES_USER: postgres
      POSTGRES_DB: postgres

volumes:
  node-modules:
  postgres-data:

volumes/app/node_modulesを設定することで、ホストからfrontendディレクトリをマウントした後に、Volumesに保存されたnode_modulesで上書きしてくれるようです。これによって、ホスト側のコードをマウントした時に、コンテナ側のnode_modulesの中身が消えるのを防ぎます。

/.devcontainer/devcontainer.json
{
  "name": "jot-blox-dev",
  "dockerComposeFile": "docker-compose.yml",
  "service": "app",
  "workspaceFolder": "/workspace",
  "customizations": {
    "vscode": {
      "extensions": [
        "Shopify.ruby-lsp",
        "Hridoy.rails-snippets",
        "castwide.solargraph",
        "misogi.ruby-rubocop",
        "kaiwood.endwise",
        "dbaeumer.vscode-eslint",
        "esbenp.prettier-vscode",
        "streetsidesoftware.code-spell-checker"
      ]
    }
  }
}

作成したdocker-compose.ymlやコンテナ内の実行フォルダ名、コンテナでVS Codeのエディタを開いた場合にインストールしておく拡張機能を設定しています。

以上設定の上、「フォルダーをコンテナーで開く」などのコマンドを実行することでコンテナ内の開発環境でエディタを立ち上げることができました。

なお、DevContainers拡張ではローカルのgit設定やsshキーの共有昨日が備わっているため、sshエージェントにキーを追加していればgithubへのpush等も開発コンテナから行えます。

感想

当初は、backendコンテナとfrontendコンテナをdocker composeで起動して開発環境を用意する想定でした。
しかしアタッチするのはどれか一つのコンテナになるので、それだとbackendコンテナ、frontendコンテナ、ローカルと行き来する必要が出てきて面倒だったので、今回backendとfrontendをまとめて一つのコンテナに収める形としました。
これが最善なのかは微妙(そもそもモノリポがどうなのかというのもある?)なところですが、少なくともローカル環境をほぼ汚さずに開発環境を用意することができました。
あとは動かしながら、動作面とか問題ないかみていきたいです。

参考

https://zenn.dev/yumemi_inc/articles/3d327557af3554
https://jdlm.info/articles/2016/03/06/lessons-building-node-app-docker.html
https://containers.dev/guide/dockerfile
https://zenn.dev/nayushi/articles/5d577c93e03a9b#意気揚々と試してみる
https://okash1n.works/posts/how-to-use-git-inside-vscode-dev-container/

Discussion