この記事では、Dockerを使用してRails7 + PostgreSQL + esbuildの環境構築の方法を解説しています。
環境
以下のような環境で利用してます。
- MacBookPro(M1)
- docker desktop
手順
順番としては以下になります。
- Dockerfile.dev、docker-compose.ymlの作成
docker-compose build
の実行docker compose run --rm app gem install rails
の実行docker compose run --rm app rails new . -d postgresql -j esbuild
の実行config/database.yml
、package.json
、Procfile.dev
の編集- DBの作成
Dockerfile.dev、docker-compose.ymlの作成
まず、今回作成するフォルダの内容としては下記のようになります。
任意のフォルダ名(今回はmy_appとします)
├── // ここにRailsの各ディレクトリが生成されます(appなど)
├── Dockerfile.dev
└── docker-compose.yml
最初に下記コマンドで大元のフォルダを作成してください。
mkdir my_app
次に下記コマンドで上記で作成したフォルダに移動します。
cd my_app
次に下記コマンドでDockerfile.dev、docker-compose.ymlの作成をします。
touch Dockerfile.dev docker-compose.yml
作成できたらそれぞれのファイルに下記内容を記載してください。
Dockerfile.dev
Rails7.1からrails new
で新規プロジェクトを立ち上げると、Dockerfile
が自動的に作成されるようになりました。
他の方の記事を参考にさせてもらい環境を構築しようとしていたのですが、ファイル名をDockerfile
のまま行っているとrails new
したタイミングでファイルが上書きされてしまっていたので、Dockerfile.dev
として上書きされないようにしています。
Dockerfile.dev
には下記を記載してください。
FROM node:20.12.0-alpine as node
RUN apk add --no-cache bash curl && \
curl -o- -L https://yarnpkg.com/install.sh | bash -s -- --version 1.22.19
FROM ruby:3.3.0-alpine
COPY /usr/local/bin/node /usr/local/bin/node
COPY /usr/local/bin/npm /usr/local/bin/npm
COPY /usr/local/bin/npx /usr/local/bin/npx
COPY /opt/yarn-* /opt/yarn
RUN ln -fs /opt/yarn/bin/yarn /usr/local/bin/yarn
RUN apk add --no-cache git build-base libxml2-dev libxslt-dev postgresql-dev postgresql-client tzdata bash vim && \
cp /usr/share/zoneinfo/Asia/Tokyo /etc/localtime
ENV APP_ROOT /app
RUN mkdir $APP_ROOT
WORKDIR $APP_ROOT
ENV LANG=ja_JP.UTF-8 \
BUNDLE_JOBS=4 \
BUNDLE_RETRY=3 \
EDITOR=vim
RUN gem update --system && \
gem install --no-document bundler:2.5.7
RUN bundle config set force_ruby_platform true
ポイント1
Dockerfile.dev
ではRailsをインストールしていません。
Railsプロジェクト内にはGemfile
とGemfile.lock
があるはずで、そちらを参照して正しいバージョンのRailsをインストールするべきだからです。
ポイント2
esbuild
の環境にはnode
とyarn
が必要になっており、node
のイメージをセットアップした後に、Rubyのイメージへ必要なファイルをコピーしています。
docker-compose.yml
docker-compose.ymlには下記を記載してください。
version: '3'
services:
app:
build:
context: .
dockerfile: "Dockerfile.dev"
stdin_open: true
tty: true
ports:
- 3000:3000
command: /bin/sh -c "bundle install && yarn install && rm -f tmp/pids/server.pid && bin/dev"
environment:
DB_USER: postgres
DB_PASS: postgres
DB_HOST: postgres
DB_PORT: 5432
depends_on:
- postgres
volumes:
- .:/app:delegated
- node-modules:/app/node_modules:delegated
- bundle-data:/usr/local/bundle:delegated
postgres:
image: postgres:16.2
stdin_open: true
tty: true
restart: always
ports:
- 5432:5432
environment:
PGDATA: /var/lib/postgresql/data/pgdata
POSTGRES_USER: postgres
POSTGRES_PASSWORD: postgres
TZ: Asia/Tokyo
volumes:
- pgsql-data:/var/lib/postgresql/data:cached
volumes:
pgsql-data:
bundle-data:
node-modules:
ポイント1
command
の箇所でRailsサーバーを起動する前にbundle install
を実行しています。
この記載を行うことで、もしGemfileに変更があったとしても、コンテナを起動する前にgemの変更点が適用されます。
ポイント2
command
の箇所でRailsサーバーを起動する前にyarn install
を実行しています。
この記載を行うことで、もしpackage.jsonに変更があったとしても、コンテナを起動する前にpackage.jsonの変更点が適用されます。
ポイント3
/usr/local/bundleをvolumeにマウントすることにより、bundle install
で作成されたbundleデータが永続化されるようにしています。
ポイント4
/app/node_modulesをvolumeにマウントすることにより、yarn install
で作成されたnode_modulesのデータが永続化されるようにしています。
docker-compose buildの実行
上記で記載した環境を構築するため一度docker-compose build
を実行してください。
docker compose run --rm app gem install railsの実行
下記コマンドを実行すると、最新のRailsがインストールされます。
docker compose run --rm app gem install rails
docker compose run --rm app rails new . -d postgresql -j esbuildの実行
このまま実行するとアプリの名前が App になるので、変えたい場合は -n アプリの名前 のオプションを追加してください。
また、DBにはPostgreSQLを使用しますよというオプションとビルドはesbuildを使用しますよというオプションをつけています。
docker compose run --rm app rails new . -d postgresql -j esbuild
config/database.yml、package.json、Procfile.devの編集
rails関係のファイルが作り終わったらconfig/database.yml
、package.json
、Procfile.dev
を下記のように修正します。
config/database.yml
default: &default
# 省略
username: <%= ENV['DB_USER'] %>
password: <%= ENV['DB_PASS'] %>
host: <%= ENV['DB_HOST'] %>
package.json
,
"scripts": {
"build:js": "esbuild app/javascript/*.* --bundle --sourcemap --outdir=app/assets/builds",
"build": "yarn build:js"
}
Procfile.json
web: bin/rails server -b 0.0.0.0 -p 3000
js: yarn build:js --watch
ポイント1
CSSのコンパイルが必要になった時のために"scripts"
で"build:js"
と"build"
に分けています。
また、Herokuなどにデプロイした時は"build"
のscriptが実行されるため"build"
も用意しています。
ポイント2
CSSのコンパイルが必要になった場合はpackage.json
の"scripts"
に追加しましょう。
そして、追加したscriptsを実行できるようにProcfile.dev
にも追記をするのを忘れずに!
下記が、tailwind cssを使った例になります。
package.json
"scripts": {
"build:js": "esbuild app/javascript/*.* --bundle --sourcemap --outdir=app/assets/builds",
"build:css": "tailwindcss -i ./app/assets/stylesheets/application.tailwind.css -o ./app/assets/builds/application.css",
"build": "yarn build:js && yarn build:css"
}
Procfile.dev
web: bin/rails server -b 0.0.0.0 -p 3000
js: yarn build:js --watch
css: yarn build:css --watch
ここまで来れたら下記コマンドを実行して、DBを作成するためにpostgresコンテナだけを立ち上げましょう。
docker compose up postgres -d
DBの作成
postgresが立ち上がったら下記コマンドを実行してDBを作成してください。
docker compose run --rm app rails db:create
これでdevelopment用とtest用のDBが作成されます。
DBが作成されたら、下記コマンドを実行してpostgresコンテナを停止させましょう。
docker compose stop postgres
postgresコンテナが停止できたら、下記コマンドを実行してRailsサーバーを起動します。
docker compose up
ここまで来たらhttp://localhost:3000にアクセスしてみましょう。
Railsのアイコンが表示されたら完了です!お疲れ様でした。