LoginSignup
4
2

Ruby on Rails 7.1 with Bootstrap on Docker Compose 開発環境を構築する方法

Last updated at Posted at 2023-11-16

はじめに

前回は、Rails 7.1 により自動生成された Dockerfile の中身を一通り確認してみましたが、

今回は、いよいよ、実際にコンテナを起動してみて、動作確認を行なっていきます。1

と言っても、自動生成される Dockerfile は、本番環境での使用に向けて調整されたものになっているので、まずは、開発環境として利用するために、少し弄らせてもらうことにしましょう。

改めて rails new を実行しよう

Dockerfile を自動生成する際の( 特に CSS フレームワークをオプションで指定する場合の )注意点については、すでに別の記事にも書いているので、詳細は割愛しますが、

結論から言えば、以下のような手順で、必要なファイル群を自動生成( rails new )していきます。

Rails 環境の確認

ここでは、rails new するためだけに、次のようなコンテナを利用しますが、適宜、自分の環境で、各種ツールのバージョンを確認してもらえれば、それでも構いません。

docker run --rm -v .:/content -w /content -it ruby:3.2.2 bash

ともかく、rails をインストール、もしくは 7.1 に更新して、バージョンを確認しておいてください。

gem install rails

↓( バージョンを確認 )

# rails --version
Rails 7.1.2

Node 環境の確認

今回は、rails new を実行する際、css オプションで Bootstrap を指定する予定なので、Node 環境も確認しておきます。2

お好みに合わせて、バージョンを調整しておきましょう。

apt-get update -qq && apt-get install --no-install-recommends -y npm
npm install -g n
n lts

↓( バージョンを確認 )

# node --version
v20.9.0

Yarn 環境の確認

同様に、とりあえず、Yarn 環境もあった方が良さそうなので、必要に応じて、確認しておいてください。2

npm install --global yarn

↓( バージョンを確認 )

# yarn --version
1.22.21

rails new の実行

さて、環境は整ったので、そろそろ rails new を実行していきます。

rails new . --database=postgresql --css=bootstrap

ちなみに、オプションとして、データベースには、PostgreSQL も指定しておきました。

これで、各種ファイルが、正常に生成されましたでしょうか?

開発環境用の Dockerfile も作ろう

コンテナ内で作業していたとしても、ちゃんとマウントされていれば、ローカルにも、以下のようなファイル群が生成されているはずです。

% ls
.dockerignore   .gitignore      Dockerfile      Procfile.dev    app/            config.ru       log/            public/         tmp/
.git/           .node-version   Gemfile         README.md       bin/            db/             node_modules/   storage/        vendor/
.gitattributes  .ruby-version   Gemfile.lock    Rakefile        config/         lib/            package.json    test/           yarn.lock

それでは、次のようにコピーして、本番環境用の Dockerfile.prod も確保しつつ、開発用として Dockerfile を編集していきたいと思います。

cp Dockerfile Dockerfile.prod

試しに「 本番環境での使用に向けて調整されている部分を、あえて逆調整する 」なら、例えば、以下のような感じになるでしょうか?

Dockerfile
# syntax = docker/dockerfile:1

# Make sure RUBY_VERSION matches the Ruby version in .ruby-version and Gemfile
ARG RUBY_VERSION=3.2.2
FROM registry.docker.com/library/ruby:$RUBY_VERSION-slim as base

# Rails app lives here
WORKDIR /rails

# Install packages needed to build gems and node modules
RUN apt-get update -qq && \
    apt-get install --no-install-recommends -y build-essential curl git libpq-dev libvips node-gyp pkg-config python-is-python3 postgresql-client

# Install JavaScript dependencies
ARG NODE_VERSION=20.9.0
ARG YARN_VERSION=1.22.21
ENV PATH=/usr/local/node/bin:$PATH
RUN curl -sL https://github.com/nodenv/node-build/archive/master.tar.gz | tar xz -C /tmp/ && \
    /tmp/node-build-master/bin/node-build "${NODE_VERSION}" /usr/local/node && \
    npm install -g yarn@$YARN_VERSION && \
    rm -rf /tmp/node-build-master

# Install application gems
COPY Gemfile Gemfile.lock ./
RUN bundle install && \
    rm -rf ~/.bundle/ "${BUNDLE_PATH}"/ruby/*/cache "${BUNDLE_PATH}"/ruby/*/bundler/gems/*/.git && \
    bundle exec bootsnap precompile --gemfile

# Install node modules
COPY package.json yarn.lock ./
RUN yarn install

# Precompile bootsnap code for faster boot times
RUN bundle exec bootsnap precompile app/ lib/

# Entrypoint prepares the database.
ENTRYPOINT ["/rails/bin/docker-entrypoint"]

# Start the server by default, this can be overwritten at runtime
EXPOSE 3000
CMD ["./bin/rails", "server"]

本番環境用の環境変数の設定とか、マルチステージビルドだとか、non-root ユーザーの作成などといった部分を、単に、根こそぎ削除してみました。3

今回は、これでうまく動くかどうか、ビルドしてみるとしましょう。

compose.yaml を作成しよう

次に、Rails と PostgreSQL のコンテナを、Docker Compose を使って、簡単に立ち上げ、連携させるために、compose.yaml ファイルを作成していきます。

この辺については、昔からお世話になっている「 Quickstart: Compose and Rails 」が、未だに参考になりますね。4

compose.yaml
services:
  db:
    image: postgres:16.1-alpine
    volumes:
      - ./tmp/db:/var/lib/postgresql/data
    environment:
      POSTGRES_PASSWORD: password
  web:
    build: .
    command: bash -c "rm -f tmp/pids/server.pid && bundle exec rails s -p 3000 -b '0.0.0.0'"
    volumes:
      - .:/rails
    ports:
      - "3000:3000"
    depends_on:
      - db

一応、PostgreSQL 5 のバージョンも、固定しておきました。6

関連して、config/database.yml を編集し、データベースの設定も整えておきましょう。

config/database.yml
(...)

default: &default
  adapter: postgresql
  encoding: unicode
+ host: db
+ username: postgres
+ password: password
  # For details on connection pooling, see Rails configuration guide
  # https://guides.rubyonrails.org/configuring.html#database-pooling
  pool: <%= ENV.fetch("RAILS_MAX_THREADS") { 5 } %>

development:
  <<: *default
  database: content_development

(...)

要するに、以下の三行を追加するだけですね。

  host: db
  username: postgres
  password: password

コンテナを起動しよう

それでは、次のコマンドを実行して( ビルドしつつ )コンテナを起動しましょう。

docker compose up -d --build

ここまでで、起動自体はできているはずですが、接続するデータベースが存在しないとエラーになってしまうので、次のコマンドで作成しておきます。

docker compose run --rm web rails db:create

そして、http://localhost:3000 にアクセスし、ちゃんと Rails が動いているかどうか、確認してみてください。

次のような「 ウェルカムページ 」が表示されれば、とりあえずは、成功です。

Screenshot 2023-11-15 at 17-24-11 Ruby on Rails 7.1.2.png

ただ、これだけだと「 本当に Bootstrap が使えるようになっているのか? 」までは分かりませんし、今後、その他の確認を行なっていくためにも、次のようなコマンドを実行するなりして、適当なページを作成しておきます。

docker compose run --rm web rails generate controller Articles index

Bootstrap も動作確認しよう

最後に、Bootstrap が使えるようになっているかどうかを確認するため、例として app/views/layouts/application.html.erb を編集し、Navbar を導入してみましょう。

ほとんどコピペですが、以下のように、body を更新してみてください。

app/views/layouts/application.html.erb
(...)

  <body>
    <nav class="navbar navbar-expand-lg bg-body-tertiary">
      <div class="container-fluid">
        <a class="navbar-brand" href="#">Navbar</a>
        <button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbarSupportedContent" aria-controls="navbarSupportedContent" aria-expanded="false" aria-label="Toggle navigation">
          <span class="navbar-toggler-icon"></span>
        </button>
        <div class="collapse navbar-collapse" id="navbarSupportedContent">
          <ul class="navbar-nav me-auto mb-2 mb-lg-0">
            <li class="nav-item">
              <a class="nav-link active" aria-current="page" href="#">Home</a>
            </li>
            <li class="nav-item">
              <a class="nav-link" href="#">Link</a>
            </li>
            <li class="nav-item dropdown">
              <a class="nav-link dropdown-toggle" href="#" role="button" data-bs-toggle="dropdown" aria-expanded="false">
                Dropdown
              </a>
              <ul class="dropdown-menu">
                <li><a class="dropdown-item" href="#">Action</a></li>
                <li><a class="dropdown-item" href="#">Another action</a></li>
                <li><hr class="dropdown-divider"></li>
                <li><a class="dropdown-item" href="#">Something else here</a></li>
              </ul>
            </li>
            <li class="nav-item">
              <a class="nav-link disabled" aria-disabled="true">Disabled</a>
            </li>
          </ul>
          <form class="d-flex" role="search">
            <input class="form-control me-2" type="search" placeholder="Search" aria-label="Search">
            <button class="btn btn-outline-success" type="submit">Search</button>
          </form>
        </div>
      </div>
    </nav>
    <div class="container-fluid mt-2">
      <%= yield %>
    </div>
  </body>
</html>

これで、http://localhost:3000/articles/index にアクセスすると、次のように表示されるでしょうか?

Screenshot 2023-11-15 at 17-41-33 Content.png

ちなみに、自動的にインストールされた Bootstrap のバージョンについては、package.jsonyarn.lock ファイルを参照するか、以下のようにコマンドを実行するなどして、確認することができます。

% docker compose run --rm web npm show bootstrap version
5.3.2

import maps について

ところで、上で追加した Navbar ですが、Dropdown を押してみてください。ちゃんと機能しているでしょうか?

ここまで、全く同じように作業してきた場合、おそらく、CSS については、確かにコンパイルされているのですが、実は、Bootstrap が利用する JavaScript の方は、たぶん読み込まれていません。

ブラウザのデベロッパーツールにも、次のようなエラーが出ているはずです。

Uncaught TypeError: Failed to resolve module specifier "bootstrap". Relative references must start with either "/", "./", or "../".

Rails 7 からデフォルトになったらしい、import maps 7 の設定ファイルを確認してみると、やはり Bootstrap は含まれていないようですね。

config/importmap.rb
# Pin npm packages by running ./bin/importmap

pin "application", preload: true
pin "@hotwired/turbo-rails", to: "turbo.min.js", preload: true
pin "@hotwired/stimulus", to: "stimulus.min.js", preload: true
pin "@hotwired/stimulus-loading", to: "stimulus-loading.js", preload: true
pin_all_from "app/javascript/controllers", under: "controllers"

いずれは、自動的に追加されるようになるかもしれませんが、例えば、次のようなコマンドを実行すれば、Bootstrap を追加することができます。

docker compose run --rm web bin/importmap pin bootstrap

これで、上の設定ファイルに、以下の二行が追記され、Dropdown も動くようになっているはずです。

pin "bootstrap", to: "https://ga.jspm.io/npm:bootstrap@5.3.2/dist/js/bootstrap.esm.js"
pin "@popperjs/core", to: "https://ga.jspm.io/npm:@popperjs/core@2.11.8/lib/index.js"

場合によっては、import maps さえあれば、Node や Yarn は必要ないようですし、JavaScript 周りについては、改めて整理した方が良さそうですね。

詳細は、Rails ガイドなどを参照してください。

おわりに

もう少し触ってみないことには、どのような問題が潜んでいるか、定かではありませんが、まぁ、最低限の開発環境として、スタートラインには立てたと言って良いでしょうか?

ちなみに、Bootstrap Icons 8 も、すでに使えるようになっているようです。

ともかく、これをベースとして、色々と試してみるとしましょう。

  1. ちなみに、今回、利用した PC は、MacBook Pro( 13-inch, M1, 2020 )で、macOS Sonoma 14.1.1 環境です。

  2. 詳細については、以前の記事 もご参照ください。 2

  3. 元の Dockerfile の内容については、前回の記事 をご参照ください。

  4. ただし、今回の Dockerfile では、Rails の WORKDIR/rails を利用しているので、compose.yamlvolumes の指定と合うよう、調整が必要です。

  5. https://hub.docker.com/_/postgres

  6. 長らく latest を使っていると、ふいにメインバージョンを上げてしまって、マウントしているデータとの整合性に問題が発生し、起動できなくなってしまう可能性があるので、ご注意ください。

  7. https://github.com/rails/importmap-rails

  8. https://icons.getbootstrap.com/

4
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
4
2