0. はじめに
DockerでRails7の環境を構築する手順(2024/02時点)です。
Javascript:esbuild
DB:MySQL8
CSS:Bootstrap
で作ります。
うまく動かないところがあったので改めて書き直しています。
1. 環境
環境: MacOS Sonoma(14.2.1)
CPU: M1
Docker Desktopはインストール済
$ docker -v
Docker version 25.0.2, build 29cf629d
$ docker compose version
Docker Compose version v2.23.3
2. ディレクトリ
ディレクトリ構成
rails7appディレクトリを作成し、配下にdockerディレクトリを作成。
mkdir rails7app
cd rails7app
3. 各種設定ファイルを作成
- railsappフォルダにrailsを構築。Dockefileを分けておかないと、Rails7構築時に上書きされてしまう。
- docker3.0以降docker-compose.ymlではなく、compose.yamlを使う。
- compose.yaml,DockerfileとGemfile、Gemfile.lockはカレントに置いて、Dockefileでrailsのルートにコピー。
- entrypoint.shは後ほど使うので空のファイル。
touch {compose.yaml,Dockerfile,Gemfile,Gemfile.lock,entrypoint.sh} && mkdir railsapp
この時点でのtree
rails7app
├── Dockerfile
├── Gemfile
├── Gemfile.lock
├── compose.yaml
├── entrypoint.sh
└── railsapp/
4. Dockerfileの記述
- のちのちrails dbconsoleをする場合、mysql-clientが必要だが、mariadb-clientに統合された
- curl -fsSLの部分はnodeのlts(v18.0)をインストールするために必要。ruby3.2.0のイメージでは、nodeのバージョンが12で古すぎるため。
- ENVで環境変数としてAPPのルートを渡す
FROM ruby:3.2.0
ENV APP /railsapp
ENV LANG C.UTF-8
ENV TZ Asia/Tokyo
RUN curl -fsSL https://deb.nodesource.com/setup_lts.x | bash -
RUN apt update -qq \
 && apt install -y build-essential mariadb-client nodejs \
 && npm install --global yarn
RUN yarn add @fortawesome/fontawesome-free @fortawesome/fontawesome-svg-core @fortawesome/free-brands-svg-icons @fortawesome/free-regular-svg-icons @fortawesome/free-solid-svg-icons
WORKDIR $APP
COPY Gemfile $APP/Gemfile
COPY Gemfile.lock $APP/Gemfile.lock
RUN bundle install
5. Gemfileの記述
バージョンは固定しておいた方が無難
最新のrailsバージョンを調べる
gem search -ra "^rails$"
*** REMOTE GEMS ***
rails (7.1.3, 7.1.2, 7.1.1, 7.1.0, 7.0.8, 7.0.7.2, 7.0.7.1, 7.0.7, 7.0.6, 7.0.5.1, 7.0.5, 7.0.4.3, 7.0.4.2, 7.0.4.1, 7.0.4, 7.0.3.1, 7.0.3, 7.0.2.4, 7.0.2.3, 7.0.2.2, 7.0.2.1, 7.0.2, 7.0.1, 7.0.0, 6.1.7.6,.........
7.1.3のようだ(2024/02/13時点)
source 'https://rubygems.org'
gem 'rails', '~>7.1.3'
6. compose.yaml
Docker Desktop v3.0.0から色々変わった。
- docker-composeはdockerコマンドのサブコマンドになった。
 docker-compose ~ではなくdocker compose ~と実行する
- 設定ファイルであるdocker-compose.ymlはcompose.yamlに変わった。
- version指定が必要なくなった。
- /usr/local/bundleをgemdataとしてvolumeマウントさせないと、gem周りでエラーが出まくる。
services:
  db:
    restart: always
    image: mysql:8.0
    # DBのレコードが日本語だと文字化けするので、utf8mb4をセットする
    command: mysqld --character-set-server=utf8mb4 --collation-server=utf8mb4_unicode_ci
    volumes:
      - type: volume
        source: mysqldata
        target: /var/lib/mysql
    environment:
      MYSQL_ROOT_PASSWORD: password
      TZ: "Asia/Tokyo"
    ports:
      - '3306:3306'
  webapp:
    #buildの"."はカレント(.)にあるDockerfileを参照してbuildしろということ
    build: .
    #rails7ではrails sではなく.bin/devでwebサーバーを起動させる(development)
    command: bash -c "rm -f tmp/pids/server.pid && ./bin/dev"
    volumes:
      - type: bind
        source: ./railsapp
        target: /railsapp
      - type: volume
        source: gemdata
        target: /usr/local/bundle
      - type: volume
        source: node_modules
        target: /railsapp/node_modules
    ports:
      - "3000:3000"
    depends_on:
      - db
    stdin_open: true
    tty: true
    environment:
      MYSQL_PASSWORD: password
      TZ: "Asia/Tokyo"
volumes:
  gemdata:
  node_modules:
  mysqldata:
7. railsプロジェクトを作る
- 以前はデフォルトでjavascriptアプローチがesbuildになっていたが、7.1.3ではesbuildを明示してやる必要がある。
docker compose run --rm --no-deps webapp rails new . --force --css bootstrap --javascript esbuild --database mysql
このコマンドを打つとずらずらとrailsファイルが作成される。
- オプション
 --force : ファイルが存在する場合に上書き
 --css : cssプロセッサでbootstrapを指定
 --javascript : javascriptアプローチでesbuildを指定
 –-database : データベースの種類(デフォルトがsqlite3なので、それ以外の時は指定する。)
 ※重要!!!
 –-skip-bundleでスキップしてはいけません。
8. config/database.yml
railsapp/config以下のdatabase.ymlを編集する。
default: &default
  adapter: mysql2
  encoding: utf8mb4
  pool: <%= ENV.fetch("RAILS_MAX_THREADS") { 5 } %>
  username: root
  password: password
  # この部分はmysqlコンテナを指定
  host: db
  # portを指定しないとMySQL connectエラーになりdbを作成できない
  port: 3306
9. Procfile.dev
「-b 0.0.0.0 -p 3000」を付加する。これが無いとlocalhostでアクセスできない。
-pはコンテナ側でLISTENしているポート
# web: unset PORT && env RUBY_DEBUG_OPEN=true bin/rails server
web: unset PORT && env RUBY_DEBUG_OPEN=true bin/rails server -b 0.0.0.0 -p 3000
js: yarn build --watch
css: yarn watch:css
10. MySQLのDBを作成
docker compose run --rm webapp rails db:create
11. コンテナの作成と起動
-dをつけることでバックグラウンドで起動
docker compose up -d
12. サーバの起動を確認
13. bootstrapの確認
確認用のcontrollerを作成し、viewを作成
コンテナをupさせたまま行うのでrunではなくexecで
docker compose exec webapp rails g controller hello index
bootstrapが適用されているか確認するために
app/views/hello/index.html.erbを以下のように書き換えます。
<div class="container">
  <h1>Hello#index</h1>
  <p>Find me in app/views/hello/index.html.erb</p>
  <div class="btn-group">
    <button type="button" class="btn btn-danger dropdown-toggle" data-bs-toggle="dropdown" aria-expanded="false">
      Action
    </button>
    <ul class="dropdown-menu">
      <li><a class="dropdown-item" href="#">Action</a></li>
      <li><a class="dropdown-item" href="#">Another action</a></li>
    </ul>
  </div>
  <div>
    <h5>
      Fontawesome Icon
    </h5>
    <div style="font-size: 5rem; color: cornflowerblue;">
      <i class="fas fa-space-shuttle"></i>
      <i class="fas fa-snowman"></i>
      <i class="fas fa-kiwi-bird"></i>
    </div>
  <div>
  <div>
    <h5>
      Bootstrap Icons
    </h5>
    <div style="font-size: 5rem; color: orange;">
      <i class="bi bi-boxes"></i>
      <i class="bi bi-radioactive"></i>
      <i class="bi bi-alarm"></i>
    </div>
  </div>
</div>
http://localhost:3000/hello/index
下のようになっていればOK。bootstrapの体裁になっている。
Actionのドロップダウンも有効になっている(esbuildが効いているということ)。
この時点ではbootstrapだけ。fontawesomeのアイコンはインストールされていないので表示されていない。

14. Fontawesomeの設定
※ここからは筆者の好みなので必須ではありません。
 Fontawesomeのインストールは済。(Dockerfileに記載)
app/javascript/application.jsに以下を追加
import '@fortawesome/fontawesome-free'
import { fas } from '@fortawesome/free-solid-svg-icons'
import { far } from '@fortawesome/free-regular-svg-icons'
import { fab } from '@fortawesome/free-brands-svg-icons'
import { library } from "@fortawesome/fontawesome-svg-core";
library.add(fas, far, fab)
先ほどは表示されていなかったFontawesomeのアイコンが表示されるようになった。

参考
