個人的Rails開発環境構築2024

2024/03/17に公開

新規でRailsプロジェクトを始める時の個人的な環境構築についてまとめる。前提とする条件等は下記。

  • 規模: ~中規模
  • 開発者数: 個人
  • 利用シーン: PoC作成・スタートアップ立ち上げ・並の業務アプリ開発等

基本戦略

利用シーン的に「思い立ったらすぐアプリの開発ができる」という感じの運用がしたい。極力セットアップで悩みたくないから必要なミドルウェアなどは全部Dockerでインストールできるようにして立ち上げれば終わり、の環境を作る。その環境の中で色々とコマンドを叩いたり、rails newrails gなどでRailsアプリを作成していく。

この辺のRailsの初期セットアップの手間を出来るだけ省きたいのでtemplateとなるリポジトリを作成し、そこからcloneしてくるだけでOKにする。

フロントエンドはReactなどを使わずをRails標準のerbとHotwireを軸に開発する。開発時はHMRの恩恵を受けたいのでその辺の設定は頑張る。

あとはLinter/Formatterの設定やCIの初期設定あたりをちゃんとやっておく感じで。

作成したテンプレ&使い方

先に上記の要望を満たすために作成した環境の使い方を書いておく。

テンプレートリポジトリをcloneする。
https://github.com/YuheiNakasaka/rails-template

git clone git@github.com:YuheiNakasaka/rails-template.git sample-project

VSCodeを開いてDevContainersを実行し数分待つ。これで下記の開発環境が基本的には整う。

  • Ruby3.3/Rails7.1
  • PostgreSQL
  • Redis
  • ERB/Hotwire/Vite/TypeScript/TailwindCSS
  • ruby-lsp/Rubocop/Biome
  • RSpec/Capybara/Playwright
  • CI(GitHub Actions)
  • dotenv

あとはbundle installnpm installなどの依存のインストールとcreate dbmigrateあたりのDB作成をしてbin/devすればlocalhost:3000でアプリが動く。諸々のauto format/lintの設定やviteによるHMRな設定がすでにできているのであまり考えることなくフロントエンド開発に入れるはず。

解説

以下では上記の技術選択をした理由やセットアップの方法などについて簡単に書いていく。

VSCode/Baseコンテナ

VSCodeを使うのはエディタとして便利なのもあるが何よりDevContainersが便利。プロジェクトをVSCodeで開いたらそのプロジェクト専用の開発環境がコンテナで整うという体験はローカルに複数のRailsアプリ環境を持つ必要のある自分のような人間には個人的には楽。VSCodeを使ってる人であれば特に指示しなくてもDevContainerを使ってくれれば同じ環境を共有できるというのも良い。

DevContainerで立ち上げるBaseコンテナとしてはYuheiNakasaka/docker-rails-basisを使っている。クジラに乗ったRuby: Evil Martians流Docker+Ruby/Rails開発環境構築(更新翻訳)で紹介されている環境を元に自分用にまとめただけ。

よくコンテナを立ち上げるとrailsサーバーまで立ち上げちゃうような環境もあるけど自分はローカルでいろんなコマンド(rails generateとか)を叩くことが多いからBaseコンテナはtty: trueにしてある。

Baseコンテナの中身は.dockerdev/Dockerfileにある。

内容的には基本的な依存ミドルウェア(Ruby,PostgreSQL,Redis,Node.js等)を入れたもの。一応あると便利なのでcurlとかvimとかも入ってる。

VSCode拡張

拡張機能の利用は自由だけど一応下記をデフォルトで入れてる。

  • Shopify.ruby-lsp
  • biomejs.biome
  • GitHub.copilot
  • kaiwood.endwise
  • VisualStudioExptTeam.vscodeintellicode
  • bradlc.vscode-tailwindcss

Auto Lint/Formattingなどの設定に加えてGitHub Copilotも。もうAI無しじゃ生きていけない体になっている。

Ruby3.3/Rails7.1

一応2024/3月現在の最新。

DevContainersを開く前(というかbaseコンテナのビルド前)にdocker-compose.ymlの方でRUBY_VERSIONに好きなバージョンを設定するとそれが入る。Railsに関してはGemfileの方に好きなバージョンを設定すれば良い。

PostgreSQL

DBに関しては好きなものを使えば良いと思う。PostgreSQLは個人的にも世間的にも今はRailsで使ってるとこ多そうなのでこれにしただけ。そういえばDHHがMulti-tenancy is what’s hard about scaling web servicesの中で顧客の環境で動かすだけとか小規模ならSQLiteでもええやんみたいな話をしてたのを思い出したが一理ある。

Redis

メールの送信や外部APIとやりとりするための非同期処理なんかを書くことはほぼ必須な気がしてるからSidekiqもデフォルトで入れてしまうことも考えたがデフォルト環境としてはちょっとやりすぎかなと思いやめた。まぁでもキャッシュやセッション管理とかでRedisは使うでしょと思ったので入れてある。

ERB/Hotwire/Vite/TypeScript/TailwindCSS

フロントエンドをどうするか。ここは割と意見が分かれると思うが標準に乗るのが一番楽だとは思う。
https://railsguides.jp/v7.0/working_with_javascript_in_rails.html

Rails7ではHotwireimportmapがデフォルトになっているからJavascriptで十分で特にこだわりがないならこれを使えば良い。設定とかほぼいらないし。

あと標準ではimportmapの他にjsbundling-railsというgemが導入されてESBuildなどのバンドラを使った管理も可能。

ただ自分はTypeScriptを使いたかったりHMRやらのフロント側のエコシステム管理をシンプルにしたかったのでViteを使うことにした。導入にはVite Rubyというgemを使うと簡単。これを使うとvite.config.tsをいじるだけでいつものように管理できるようになる。assets:precompileと自動で統合されてるからデプロイも楽だしPluginも必要なものが揃っているからrails側のviewとjsの変更を検知してViteの高速なHMRを導入するのも楽々。

基本的なフロントエンドのコードはERBで書く。SlimとかHamlは無駄に標準から外れる気がするしあんまり使ってて嬉しかったことがない。Sustainable Web Development with Ruby on Railsでもそんなこと言ってたような。

フォームでの更新やフロントエンドの書き換えは基本Hotwireでやっちゃうからサーバーサイドレンダリングになる。じゃあJSはいつ書くのか?となるがこれまでの経験上、なんだかんだ運用していくとStimulusでDOMをいじらないといけない要件が出てくる。しかもそういうコードこそ面倒な処理で膨れ上がったりするので最初からTSで書けるようにしてある。

Viteの導入とかの手順はここに書くと煩雑になるから書かないが、雑だけどこっちの作業メモを見ると参考になるかも。
https://scrapbox.io/razokulover-tech-memo/Rails+Stimulus+Vite+TypeScript+Biome+α

ruby-lsp/Rubocop/Biome

LinterとFormatterについて。Ruby側とJS側で設定が必要。

RubyのLSPはruby-lspを使い、Linter/FormatterはRubocopを使っている。昔はrebornix.rubyを使っていたけど非推奨になったのでShopify製のLSPにした。業務でも使ってみてるけど特に問題はなさそう。

JS側はBiomeを導入した。ESLint/Prettierが多く使われている印象だがBiomeならLintもFormattingも両方を管理してくれるし標準設定が優秀だから複雑な設定もほぼ不要で楽。

RSpec/Capybara/Playwright

テストはRSpecを使ってる。minitestでもいいんだけどこれについては標準といえど設定含めて慣れてるRspecを入れちゃっている。テストデータはfactory_botを使う。

SystemテストはCapybaraPlaywrightを使っている。SeleniumよりPlaywrightの方が安定している(諸説ある)傾向があるのでこちらを導入した。あと知らなかったんだけどPlaywrightがRails7.1以降で標準で使えるようになるらしいのでその意味でも使ってみた。
https://note.com/dev_onecareer/n/n67d25088b100

E2Eテスト、設定が面倒だったり処理時間が遅かったりして忌避されることもあるが個人的にE2Eテストは結構重要だと思っている。エンドユーザーにとっては最終的なアウトプットが正しく想定通り動いていないと意味なくて、これをE2Eテストによってある程度は保証できる。

ただまぁ不安定でCIが遅くなるのは確かだし全ての仕様を漏れなく記述しようとしたりするとコードがどんどん肥大化する。なのでどのくらいの粒度で書くのかは難しい。目安としては実際にユーザーやクライアントにアプリのURLを渡してやりそうな振る舞いから順に網羅していく感じ。このスライドが結構好き。
https://speakerdeck.com/moro/enough-good-rails-e2e-test

CI(GitHub Actions)

CIでは一応LintとTestの実行を回してる。GitHub Actionsで設定してるだけ。特に特別なことはしてない。実を言うとGitHub Actionsの設定はあんまり詳しくないので改善の余地がかなりありそう...。

秘匿情報

秘匿情報をどう管理するのかというのは一つの悩みどころである。

まず標準という観点で言うとRails Credentialsが挙がる。実際に一部のプロジェクトで使ってもいる。秘匿情報を暗号化されたファイルとしてリポジトリに入れて置けるのでmasterキーさえちゃんと管理すれば複数人開発でも楽だよねという機能。微妙ポイントとしては秘匿情報をリポジトリ管理にしてるから秘匿情報の変更時にいちいちアプリのデプロイが必要になるという点。あとはTwelve Factor Appで設定はコードから分離しろと言ってるしそもそも時代に逆行してる感もある。

そういうわけで普通に環境変数を使えば良いよな...となったので開発時の環境変数設定用にdotenvを入れている。

実行環境がAWSならParameter Storeを使うのが王道。この辺は本番環境に合わせて好きに使えば良い。

本番環境

本番環境をどこにするかという問題も悩みどころなので少し書いておく。

基本はコストを抑える/インフラ管理を極力したくないあたりの理由から初手PaaS次点で大手クラウド、みたいな優先順位になっている。

VPSで全て管理というのはある程度スケールさせ安定運用させるには中々面倒なので個人サービスや転送コストがえげつないサービスとか特別な用途以外では業務で採用しない。

スケール性と安定性を重視した本番環境を構築するならAWS/GCPのクラウドサービスを選択する。基本はECS等のマネージドのコンテナやCloud Runのサーバレス環境でアプリを動かす感じ。業務アプリならこの選択が基本。仮にどこかに引き継ぐとしてもやりやすいはず。ただしちゃんとした環境なら今だと最低でも月1万円以上コストがかかるので個人サービスやPoCとかには向かない。

AWS/GCPを使う場合の面倒ポイントとしてインフラ設定をコード化したりデプロイや監視などの諸々の構築や運用がある。この辺は特に個人サービスやスタートアップの立ち上げ時なんかだと影響がでかいのでPaaSを使うという選択を取る。昔はHeroku一択だったけどOAuthトークン流出やSkebのゴタゴタとか最近はあんまり良い印象がない。なので個人的にはKoyebRenderあたりを使う。特に最近はKoyebか。

KoyebはTokyo Regionがあるのも良い(Renderは近くだとSingaporeしかない)。GitHub Pushのデプロイかコンテナデプロイが選べるが、前者はPushするだけでいいので楽だし後者は仮にAWS/GCPへ移行する際にスムーズにできそうというそれぞれのメリットがある。難点としてはKoyeb自体がスタートアップなので継続性に不安はある。

そういえばFly.ioも触ってみたりしたけどだいぶ使いにくかった印象で使っていない。

どこのインフラを使うにしても重要なのは一つのプラットフォームで完結させること。アプリはWorkersでDBはPlanetScaleで〜みたいにインフラを複数社で色々使い分けないといけないのは運用がだるすぎる。個人レベルなら良いが自分以外が今後メンテする可能性もあるし業務では使いたくない。

まとめ

個人的なRails開発環境について書いた。今回紹介したRails環境のテンプレは下記にある。
https://github.com/YuheiNakasaka/rails-template

こういうテンプレを作っておくといざ開発に取り掛かろうと思った時にすぐ着手できるようになるので良い。今時Railsで新規開発するんか?みたいな声も聞くけど受託開発系だと普通に全然あるので気にするな。

Discussion