結論
rails7-on-docker環境のcompose.yaml
を使用してDevContainer環境を構築するのがおすすめ!
環境
- VScode
-
rails7-on-docker環境の準備が整っていること
- 他環境のDevContainer化でも参考になると思いますが、記事自体はrails7-on-railsについて言及しています。
-
rails7-on-docker
は、docker環境にrails7、postgresql、RSpecなどが入っています。いちいちrubyをインストールしたりだとかをしなくていいので便利です。 - もし環境準備がまだであればこちらの記事がおすすめです:Windows WSL Docker Rails7 環境構築
dovcontainer化する手順
VScode公式のDEV CONTAINERSのQuick start open an existing folder in a containerのところを参考に作業を進めます。
以下は、その手順を日本語で書いたものです。
-
VScode上で、
F1キー
を押してコマンドパレットを開き、「Dev Containers: Open Folder in Container...(開発コンテナ:コンテナーでフォルダを開く…)」をクリック -
rails7-on-dockerのローカルリポジトリフォルダを選択
-
「ワークスペースに構成を追加する」を選択
-
「既存の構成をワークスペースにコピーする」を選択
-
compose.yaml
を選択 -
インストールしたい拡張機能を選択
- 特になければスキップで大丈夫です。あとで追加できますし、追加したらリビルドすればいいので。
-
VScodeが自動でDevContainer構成ファイルを作成し、開発コンテナ環境をVScodeが開いてくれるのを待つ
- 新たに「.devcontainer/devcontainer.json」ファイルが作成されます。
-
VScodeの左下に「開発コンテナ:…」になっていれば完成
-
開発コンテナーを終了するときは、VScode左下の「開発コンテナー:…」をクリックし、「フォルダーをローカルで再度開く」を選択
-
DevContainerを開始するときは、VScode左下の「リモートウィンドウを開きます」をクリックし、「コンテナーでフォルダを開く…」を選択
- VScodeが
devcontainer.json
を読み込んで、起動してくれます。
- VScodeが
DevContiner構成ファイル
- 公式リファレンスページ:General devcontainer.json properties
余談
ここからは余談です。本編には関係ないですが、エンジニアには大切だと思うので、ここに記しておきます。
事象
rails7-on-dockerをクローンした環境を使用して開発していた。途中からDevContiner環境にして作業していた。
RSpecを実行してみたら、テスト結果がエラー「missing secret_key_base
for 'production' environment, set this string with bin/rails credentials:edit
」になってしまった。DevContiner化する前は、エラーは出ていなかった。いろいろ調べて試していたら、rspecだけでなくgit commit
もrails c
も、実行するとエラーが返ってきて、「何もできん」になっていることに気づいた。
原因
DevContiner環境構築時にproductionモードで実行するDockerfile
を選択していたため、productionモードで起動するようになっていた。
どうしてそうなったか
DevContainer環境構築の「既存の構成をワークスペースにコピーする」ときに、Dockerfile
を選択してしまい、productionモードで起動するDevContainer環境が出来上がってしまった。
Dockerfile
# syntax = docker/dockerfile:1
# This Dockerfile is designed for production, not development. Use with Kamal or build'n'run by hand:
# docker build -t my-app .
# docker run -d -p 80:80 -p 443:443 --name my-app -e RAILS_MASTER_KEY=<value from config/master.key> my-app
# Make sure RUBY_VERSION matches the Ruby version in .ruby-version and Gemfile
ARG RUBY_VERSION=3.3.2
FROM docker.io/library/ruby:$RUBY_VERSION-slim as base
# Rails app lives here
WORKDIR /rails
# Install base packages
RUN apt-get update -qq && \
apt-get install --no-install-recommends -y curl libjemalloc2 libvips postgresql-client && \
rm -rf /var/lib/apt/lists /var/cache/apt/archives
# Set production environment
ENV RAILS_ENV="production" \ # ←ココ
BUNDLE_DEPLOYMENT="1" \
BUNDLE_PATH="/usr/local/bundle" \
BUNDLE_WITHOUT="development"
(省略)
ちゃんとコメントに「これはプロダクションのためにデザインしたDokerfileだよ、開発用じゃないよ」と書いてありますし、ENV RAILS_ENV="production"
と設定されていますね。
compose.yml
services:
web:
build:
context: ./
dockerfile: development.Dockerfile # ←ココ
command: bash -c "rm -f tmp/pids/server.pid && bin/rails s -p 3000 -b '0.0.0.0'"
volumes:
- .:/usr/src/app
- bundle:/usr/local/bundle
ports:
- "3000:3000"
env_file:
- .env
environment:
- HISTFILE=/usr/src/app/log/.bash_history
depends_on:
db:
condition: service_healthy
redis:
condition: service_started
(省略)
ビルドするとき参照するdockerfile
は、development.Dockerfile
って書いてあります。開発環境用のDockerfileも用意してありますね(作った人ありがとう)。
DevContiner環境を作成するときに、development.Dockerfile
を選択しても多分問題なかったと思いますが、compose.yaml
がdevelopment.Dockerfile
を参照しているし、今後dockerの構成をcompose.yaml
に書くかもしれないので、今回は上記手順で構築しました。
Dockerfileとcompose.yamlについて
これについてまとめてある記事がありました。
Dockerfile と docker-compose を利用すると何がうれしいのか?
簡単に説明すると、Dockerfile
はdockerイメージ(dockerの中身)の設定を書くところで、compose.yaml
はdockerを組み合わせてアプリケーションを実行するときの設定を書くところです。
devcontainer.jsonの差分
{
"name": "rails",
"build": {
// Sets the run context to one level up instead of the .devcontainer folder.
"context": "..",
// Update the 'dockerFile' property if you aren't using the standard 'Dockerfile' filename.
"dockerfile": "../Dockerfile"
},
(略)
}
{
"name": "rails",
// Update the 'dockerComposeFile' list if you have more compose files or use different names.
// The .devcontainer/docker-compose.yml file contains any overrides you need/want to make.
"dockerComposeFile": [
"../compose.yaml",
"docker-compose.yml"
],
(略)
}
選んだファイルによって少し書き方が変わっていますね。
Dockerfile
の方は、build.dockerlife
プロパティに書かれています。
compose.yaml
の方は、dockerComposeFile
プロパティに書かれています。rails7-on-rails環境だと、dockerComposeFile
プロパティに書いてあるcompose.yaml
ファイルを参照して、そこのbuild.dockerfile
プロバティを見て、development.Dockerfile
を読みに行くんだろうなと思います。
そもそもどうしてDevContainer化しようとしたか
これこそ余談で、話せば長くなるんですが、もとはRailsチュートリアルをrails7-on-docker環境使ってやっていていたんです。んで、「3.6.2Guardによるテストの自動化」のところにきてGuard
使ってみたんですが、ファイル変更しても反応がないんですね。原因は、Guard
はコンテナ内で起動していて、ローカルのファイルを操作していたので、いくら保存しても動かないわけだわってなりました。「たしか、DevConteiner
ってコンテナの中で作業するやつがあった気がする」となり、DevContainer化しようってなりました。
そう、目的は「Guard
が動く」だったんです。DevContiner環境じゃなくても良かったんですね。他の解決方法もあったかと思いますし、DevContiner環境ができただけで、Guard
が動くかは試してみないと分かりません。
私は、問題があって、解決方法をいろいろ試しているうちに、また新たな問題に出くわして、その解決方法を調べ始めがちです。これはこれでいろんなことが学べるので悪いことではないかと思います。でも、勤務中のチームでの作業ですと、進捗に影響を与えかねません。他のメンバーからみたら迷子に見えるかもしれません。
その現場の環境や文化にもよると思いますが、報告・相談をしながら進めるといいと思います。知らせておくと、周りも状況を把握しておけますし、アドバイスがもらえるかもしれません。(私は自己学習でやっていたことなので、誰にも迷惑かけてませんよ)
まとめ・所感
Qiitaに投稿する記事はこれが初めてです。
ずらずらと長く書きましたが、ここに至るまで紆余曲折あったので許してください。今思えば、手順の話しと余談の話しで記事を分けても良かったなとも思っています。今後も時間があれば、投稿したいと思うので、読みやすさとかも考えて書いていきたいです。
最後に、この問題を解決するのに大切だと感じたことは、
- 設定ファイルの役割を把握し、内容を読むこと
- 目的を見失わないこと、たまに振り返ること
です。
DevContainer構築することによって、devcontainer.jsonだけでなく、Dockerfileのことや、Railsサーバー、RSpecなどいろいろなことを調べ、学ぶことができて良かったです。
もし、内容の不備やアドバイスがあれば、コメントいただければと思います。
読んでいただき、ありがとうございました。