はじめに
本記事は錆びかけたRailsの知識を頑張ってアップデートするアドベントカレンダーの4日目です。
前回の記事でDockerを使って環境構築を行い、そのまま猫Rails様の猫でもわかるHotwire入門 Turbo編を読み進めていました。
すると、「サーバを立ち上げるときはrails s
じゃなくてbin/dev
を使うよ」という箇所に差し掛かりました。これは全く知りませんでした。キャッチアップを怠ってきたことの老害弊害が出ているなと、早くも感じております。
また、このbin/dev
コマンドをDocker環境で利用するにあたり少しつまづいたところもあったので、そのあたりも備忘録兼ねてまとめます。
bin/devって何?
bin/dev
コマンドは、Rails7においてrails s
コマンドの代わりになるコマンドです。これまでrails s
を実行していたタイミングで利用します。
bin/devを使う理由
Rails6までとは違う手順でサーバを起動するためです。
Rails6では、webpacker
というgemによりrails s
でサーバを立ち上げたとき自動的にCSSやJavaScriptの最適化も行っていました。
webpackerはRails6においてデフォルトのgemでした。しかし、Rails7ではデフォルトではwebpackerを利用しません。代わりに、Rails7ではforeman
というプロセス管理のツールを使いサーバー起動とCSS・JavaScriptの最適化プログラムを動かします。
今回猫Rails様の本を読んでサンプルコードを動かしており、本の進行どおりアプリ作成時に--css bootstrap
というオプションを付けています。このオプションを指定した場合アプリ内にbin/devというファイルが作成され、foremanを利用してサーバの起動やJavaScript/CSSの変更反映 ~ 最適化を行うようにしてくれます。
#!/usr/bin/env bash
# foremanがインストールされていなければインストール
if ! command -v foreman &> /dev/null
then
echo "Installing foreman..."
gem install foreman
fi
# Procfile.devを元にforemanを起動
foreman start -f Procfile.dev "$@"
そして、foremanが何をしてくれるかが書いてあるのが以下のProcfile.dev
です。
# foremanが立ち上げるプロセス
# サーバー起動
web: bin/rails server -p 3000
# ファイルの変更を監視して、esbuildでJavaScriptを自動ビルド(package.jsonのbuildに対応)
js: yarn build --watch
# ファイルの変更を監視して、sassでapplication.bootstrap.scssを自動ビルド(package.jsonのbuild:cssに対応)
css: yarn build:css --watch
ここで馴染みのあるrails server
コマンドが出てきましたね。
結局のところ、bin/dev
コマンドを実行することで結果的にrails s
も実行されていたということです。
Dockerの設定ファイルを修正する
Dockerでの構築でbin/dev
コマンドを利用すべく、Dockerfileとdocker-compose.ymlを修正します。
修正方針は以下の通りです。
- Dockerfileでrails sしている部分をbin/devに変更する
- docker-compose.ymlでrails sしている部分をbin/devに変更する
FROM ruby:3.2.0
# Node.jsとYarnのインストール
RUN curl -fsSL https://deb.nodesource.com/setup_lts.x | bash - && \
apt-get update && \
apt-get install -y nodejs default-mysql-client && \
npm install -y --global yarn && \
rm -rf /var/lib/apt/lists/*
WORKDIR /myapp
# GemfileとGemfile.lockを先にコピーしてbundle install
COPY Gemfile /myapp/Gemfile
COPY Gemfile.lock /myapp/Gemfile.lock
RUN bundle install
# アプリケーションのソースコードをコピー
COPY . /myapp
# Yarnパッケージのインストール
RUN yarn install --check-files
# entrypoint.shの設定
COPY entrypoint.sh /usr/bin/
RUN chmod +x /usr/bin/entrypoint.sh
ENTRYPOINT ["entrypoint.sh"]
EXPOSE 3000
- CMD ["rails", "server", "-b", "0.0.0.0"]
+ CMD ["bin/dev"]
version: '3.8'
services:
db:
image: mysql:8.0.32
command: --default-authentication-plugin=mysql_native_password
container_name: db
ports:
- 4306:3306
volumes:
- db:/var/lib/mysql
environment:
MYSQL_ALLOW_EMPTY_PASSWORD: 'yes'
TZ: Asia/Tokyo
security_opt:
- seccomp:unconfined
app:
tty: true
stdin_open: true
container_name: app
build:
context: .
dockerfile: Dockerfile
volumes:
- .:/myapp
- bundle:/usr/local/bundle
- public-data:/myapp/public
- tmp-data:/myapp/tmp
- command: bash -c "rm -rf tmp/pids/server.pid && rails server -b 0.0.0.0 -p 3000"
+ command: bash -c "rm -rf tmp/pids/server.pid && bin/dev"
environment:
TZ: Asia/Tokyo
depends_on:
- db
ports:
- 3000:3000
volumes:
db:
driver: local
bundle:
driver: local
public-data:
driver: local
tmp-data:
driver: local
それぞれrails s
コマンドを使っているところをbin/dev
に置き換えました。
終わりに
記事を書くにあたり気づいたこと・疑問点
rm -rf tmp/pids/server.pid
はentrypoint.shにもあるし、docker-compose.ymlにある方は消して良いのかと思い消してみたら、docker-compose stop
してもdocker-compose down
してもpidファイルが消えなくなりました。コマンドが重複しているような気がするのですがどうしてでしょうか。
Docker for Desktopを確認すると、コンテナのログを簡単に確認することができて便利。