Ruby on Rails

【Rails 7】ActionText と Tailwind CSS を同時に使う場合の環境構築

ActionText と Tailwind CSS は以下の Issue にもあるように相性が悪いようで、かなり苦戦しました。なので、ここに環境構築の仕方をまとめておきたいと思います。

うまくいった構成

私が動作確認できた構成を挙げておきます。

  • Rails 7
  • esbuild
  • Tailwind CSS
  • ActionText
  • Sprocket

試行錯誤する中で、初めは JavaScript を import-map にしてましたがうまく行かず、JavaScript を esbuild にしましたが、import-map でもうまくいくかもしれません。

アセットパイプラインは Sprocket になっていることを確認してください。

Propshaft にして上と全く同じ構成で環境構築しましたが、ActionText のフォームを表示することができませんでした。

環境構築

rails new に必要なファイルを用意

以下のファイルを用意します。

  • Dockerfile
  • docker-compose.yml
  • Gemfile
  • Gemfile.lock
  • entrypoint.sh

Dockerfile

Dockerfile は以下のようにします。nodejs をインストールしたら npm も入るはずなのですがなぜか入らなかったので、個別で指定しています。

ez_web の箇所は自分のアプリ名に変えてください。

FROM --platform=amd64 ruby:3.2.2

RUN curl -sS https://dl.yarnpkg.com/debian/pubkey.gpg | apt-key add - \
  && echo "deb https://dl.yarnpkg.com/debian/ stable main" | tee /etc/apt/sources.list.d/yarn.list \
  && apt-get update \
  && curl -fsSL https://deb.nodesource.com/setup_14.x | bash \
  && apt-get install -y nodejs npm cron \
  && apt-get clean \
  && rm -rf /var/lib/apt/lists/* \
  && mkdir /ez_web

RUN npm install --global yarn

WORKDIR /ez_web
COPY Gemfile /ez_web/Gemfile

COPY Gemfile.lock /ez_web/Gemfile.lock

RUN bundle install

COPY . /ez_web

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"]

docker-compose.yml

docker-compose.yml は以下のようにします。データベースには MySQL を使っています。

version: "3"
services:
  mysql:
    platform: linux/x86_64
    image: mysql:8.0
    environment:
      MYSQL_ROOT_PASSWORD: password
    ports:
      - "3310:3306"
    command: --default-authentication-plugin=mysql_native_password
    volumes:
      - mysql_data3:/var/lib/mysql
  ez_web:
    build: .
    command: /bin/sh -c "rm -f tmp/pids/server.pid && bundle exec rails s -p 3000 -b '0.0.0.0'"
    environment:
      MYSQL_DATABASE: ez_web_db
      MYSQL_HOST: mysql
      MYSQL_USERNAME: root
      MYSQL_ROOT_PASSWORD: password
      MYSQL_PORT: 3306
    volumes:
      - .:/ez_web
      - rails_gem_data:/usr/local/bundle
    ports:
      - "3003:3000"
    depends_on:
      - mysql
    stdin_open: true
    tty: true

volumes:
  mysql_data3:
  rails_gem_data:
    driver: local

ports の箇所ですが、"3003:3000" になっています。この設定は、ホストマシンの3003 ポートをコンテナの 3000 ポートにマッピングしています。これにより、ホストマシンの3003 ポート (localhost;3003) を通じて Rails アプリケーションにアクセスできます。

Gemfile

Gemfile は以下のようにします。

source "https://rubygems.org"

ruby "3.2.2"

gem "rails", "~> 7.1.2"

Gemfile.lock

こちらは空でいいです。

entrypoint.sh

こちらは以下のようにします。

#!/bin/bash
set -e

# Remove a potentially pre-existing server.pid for Rails.
rm -f /myapp/tmp/pids/server.pid

# Then exec the container's main process (what's set as CMD in the Dockerfile).
exec "$@"

rails new する

上記のファイルを作った後、ビルドして、Rails new して新しく Rails アプリを作成します。

docker-compose build
docker-compose run --rm ez_web rails new . --force --database=mysql -j esbuild

無事完了したら、docker-compose run --rm --service-ports ez_web コマンドでサーバーを立ち上げ、ブラウザで localhost:3003 にアクセスして以下画面が表示されるのを確認します。

Tailwind CSS を導入

準備段階として、Procfile.dev の web: env RUBY_DEBUG_OPEN=true bin/rails server を削除します。

bin/dev コマンドは foreman と呼ばれるプロセス管理ツールを使っています。これで Rails サーバーを動かすと binding.pry などで止めたときに標準入力ができず、デバッグすることができません。

なので、Rails サーバーは直接動かしつつ、CSS と JavaScript は foreman に動かしてもらうようにします。

ターミナルを2つ開いてそれぞれで以下の2つのコマンドを実行して開発環境を立ち上げます。

docker-compose --rm ez_web bin/dev
docker-compose run --rm --service-ports ez_web

準備ができたら、以下の2つのコマンドを実行し、Tailwind CSS をインストールしていきます。

docker-compose --rm ez_web bundle add tailwindcss-rails
docker-compose --rm ez_web bundle exec rails tailwindcss:install

その後、Tailwind CSS を使ったページを作成して動作確認して、適用されていたら導入成功です。

以下のようなエラーが出た場合は、Rails サーバーと foreman をどちらも再起動して再度アクセスしてみてください。

Action Text を導入

まずは Action Text をインストールします。

docker-compose --rm ez_web bundle exec rails action_text:install

インストール後、マイグレーションファイルが作られるので、マイグレーションを実行します。

docker-compose --rm ez_web bundle exec rails db:migrate

次にモデルに定義を追記します。

class Post < ApplicationRecord
  has_rich_text :content # 追記
  # 略
end

Action Text のデータは先程マイグレーションしたテーブルに保存されるため、新たに content カラムを用意する必要はありません。

後は Controller と View に以下のように書き、表示できたら導入成功です。

# app/controllers/posts_controller.rb
class PostsController < ApplicationController
  def new
    @post = Post.new
  end
end

# app/views/posts/new.html.erb
<%= form_with(model: @post) do |f| %>
  <%= f.rich_text_area :content %>
<% end %>

リッチテキストボックスが出てこなかったり、以下のようにCSS が適用されていない場合はこちらの Issue のワークアラウンドを試してください。

ただ、自分はこれをやっても表示できず今回の構成でなんとかうまく表示できました。

さいごに

Action Text の導入には 3 回 Rails new をやり直すなどかなり苦戦してしましたが、上記の構成でなんとか表示することができました。

特に Tailwind CSS といっしょに使うときに不具合が起きやすいみたいなので、ハマった人はぜひ参考にしてみてください。

ABOUT ME
sakai
東京在住の30歳。元々は車部品メーカーで働いていてましたが、プログラミングに興味を持ちスクールに通ってエンジニアになりました。 そこからベンチャー → メガベンチャー → 個人事業主になりました。 最近は生成 AI 関連の業務を中心にやっています。 ヒカルチャンネル(Youtube)とワンピースが大好きです!