はじめに
今回、webアプリ(ポートフォリオ)を作成するにあたり、Herokuでのデプロイに非常に苦労しました。理由はいくつかありますが、特にDockerを使用したtailwindとdaisyuiの環境構築がうまくいかなかったことが大きな要因です。(実際にはHerokuの前にFly.ioのデプロイも試みましたが、そちらでも成功できませんでした…)
そのため、ここではDockerを使ったrails+tailwind+daisyuiの環境構築について詳しく説明したいと思います。
私自身、まだまだ未熟な未経験エンジニアですので、誤った解釈をしている可能性もあります。もしそういった場合がありましたら、ぜひコメントでご指摘いただければ幸いです。
前提
- Docker version 20.10.23
- Ruby on Rails 7.0.4
- Ruby 3.1.2
Dockerでの環境構築
こちらにも、書いていますので良ければチラッと見てみてください。
ただ、若干異なる部分があるのでこの記事にも記載しておきます。
ファイルを作成
まずは、プロジェクトを配置するフォルダを準備します。ここが Rails のルートディレクトリになります。
今回はsample-appディレクトリを作成し、その下にDockerの環境構築をしていこうと思います。
以下を順にターミナルで叩いてください。(コードエディタで直接作成しても大丈夫です)
mkdir sample-app
cd sample-app
touch Dockerfile Gemfile Gemfile.lock docker-compose.yml entrypoint.sh
それぞれのファイルに記述
それでは、先ほど作成したファイルにコードを記述していきましょう。
Dockerfile
FROM ruby:3.1.2
ENV TZ Asia/Tokyo
RUN apt-get update -qq && apt-get install -y build-essential libpq-dev nodejs && apt-get install -y vim
# Install yarn
RUN curl -sL https://deb.nodesource.com/setup_18.x | bash - \
&& wget --quiet -O - /tmp/pubkey.gpg 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 -qq \
&& apt-get install -y nodejs yarn
# 作業ディレクトリを指定
WORKDIR /sample-app
# ホストのGemfileとGemfile.lockをコンテナにコピー
COPY Gemfile Gemfile.lock /sample-app/
# bundle installを実行
RUN bundle install
# ホストのカレントディレクトリをコンテナにコピー
COPY . /sample-app/
# entrypoint.shをコンテナ内の/usr/binにコピーし、実行権限を与える
COPY entrypoint.sh /usr/bin/
RUN chmod +x /usr/bin/entrypoint.sh
# ENTRYPOINTとCMDを統合
ENTRYPOINT ["entrypoint.sh"]
CMD ["rails", "server", "-b", "0.0.0.0"]
-
sample-appと記載してありますが、おそらくなんでもいいです。私は余計なエラーを起こさないために、webアプリ名やルートディレクトリ名と同じにしています
-
curl -sL https://deb.nodesource.com/setup_18.x
で特定のバージョンのnodeをインストールすることができます。(後々、tailwindやdaisyuiを導入する時に必要ですので、nodeを入れるようにしてください)
docker-compose.yml
version: '3'
services:
db:
image: postgres
environment:
POSTGRES_USER: postgres
POSTGRES_PASSWORD: password
volumes:
- postgres_volume:/var/lib/postgresql/data
ports:
- '5432:5432'
web:
build:
context: .
dockerfile: Dockerfile
command: bash -c "rm -f tmp/pids/server.pid && bundle exec rails s -p 3000 -b '0.0.0.0'"
volumes:
- .:/sample-app
ports:
- 3000:3000
stdin_open: true
tty: true
depends_on:
- db
volumes:
postgres_volume:
-
db
以下は、dbコンテナの設定について記述しています -
postgres_volume:/var/lib/postgresql/data
は、/dataまでpathを指定しないとdbの永続化できないです。また、永続化しないとdocker-compose down
するたびにdbを作成しないといけず非常に手間なのでここで永続化しておきます。 -
web
以下は、アプリ側の設定を記述しています -
stdin_open: true
は、dockerコンテナを起動したままにできる。コンテナ内に入ってコマンドを打ち込めます -
tty: true
は、コンテナを起動させたまま、bashで入れたりできます -
volumes:
では、永続化するvolumeの名前を指定してあげます
entrypoint.sh
#!/bin/bash
set -e
# Remove a potentially pre-existing server.pid for Rails.
rm -f /sample-app/tmp/pids/server.pid
# Then exec the container's main process (what's set as CMD in the Dockerfile).
exec "$@"
Gemfile
source "https://rubygems.org"
gem "rails", "~> 7.0.4"
ここもローカル環境のrailsのバージョンと合わした方が後々エラーになりづらいです。
もしくは、ローカル環境でrailsのバージョンを合わせるようにしましょう。
Gemfile.lock
ここは何も記述しなくて大丈夫です。
rails newする
これでrails newする準備はできたので、ターミナルで叩いていきましょう。
sample-appディレクトリのままで、下記を実行します。
docker-compose run web rails new . --force --database=postgresql
- webの部分は、docker-compose.ymlで記述した、web:の部分でこれがrails側のコンテナ名になります。
なので今後、docker-compose runやdocker-compose execなどを叩く時は、その後に指定した名前を記述してください。 - --apiをつけると、apiモードで作成できます
- --database=postgresqlでdbを導入できます。他にもmysqlなどがあります。
- --css=bootstrapなどとつけるとcssフレームワークも一緒に導入できます。他にもtailswind、bulma、postcss、sassも選べます。ただし、ここでtailwindを指定すると、tailwindcss-railsというgemが自動で導入されます。これがdaisyUIを導入できない問題につながってしまったので、ここでは指定しない方が良いです。
config/database.ymlが作成されるので、以下を記述
rails newすると、sample-app以下にたくさんファイルが作成されると思います。
その中にconfig/database.ymlがあるので、以下のように記述してください。
default: &default
adapter: postgresql
encoding: unicode
host: db
username: postgres
password: password #これは、docker-compose.ymlで指定したパスワード
pool: <%= ENV.fetch("RAILS_MAX_THREADS") { 5 } %>
development:
<<: *default
database: sample_app_development
test:
<<: *default
database: sample_app_test
production:
<<: *default
url: <%= ENV['DATABASE_URL'] %> #これを記述するだけで、あとはherokuがよしなにやってくれます
ビルドしつつ、サーバーを起動
以下をターミナルで叩きます。
docker-compose up -d --build
やっていることは下記と同じです。
docker-compose build
docker-compose up -d
localhost:3000 にブラウザでアクセス
アクセスするとActiveRecord::NoDatabaseError
が表示されると思います。
これは、dbを作成してくださいということなので、docker-compose exec web rails db:createしてください。
この画面が出たら、無事成功です。
ページの作成
tailwindとdaisyuiを当てる前に、まずはてきとーにページを作りましょう。
今回は、コンテナは起動したままコマンドを叩くため、docker-compose exec web
とします。起動していない時は、docker-compose run web
で大丈夫です。
- トップページを作成
docker-compose exec web rails g controller Tops index
-
route.rb
とtops/index.html.erb
を編集
Rails.application.routes.draw do
root "tops#index"
end
<h1 class="text-3xl font-bold underline">
Hello world!
</h1>
<button class="bg-gray-900 hover:bg-gray-800 text-white rounded px-4 py-2">tailwind</button>
<button class="btn">daisyUI</button>
http://localhost:3000/
にアクセスすると、以下のようになっていると思います。
現時点ではtailwindのスタイルとdaisyUIのスタイルがあたっていないですね。
tailwindとdaisyuiの導入
それでは、導入していきましょう。
とは言っても、tailwindとdaisyuiに関しては、下記の記事で説明してくれています。
ぜひ、一度見てみてください。
- https://zenn.dev/yoiyoicho/articles/410a7e3fd892b5
- https://qiita.com/kwtuku/items/3639e8f268f6f9a442b1
- https://qiita.com/345dvl/items/4bafb05964281079033e
導入方法としては、1.に記載してある通りなのですが、dockerを使った例をこの記事でも載せておきます。
手順
1. Gemfileに以下を記載
gem 'cssbundling-rails'
gem 'jsbundling-rails'
2. bundle install
docker-compose exec web bundle install
をターミナルで入力し、budle installします
3.tailwindをインストール
docker-compose exec web bundle exec rails css:install:tailwind
でtailwindをインストールします。
http://localhost:3000/
にアクセスすると、以下のようにtailwindが当たっていると思います。
4. yarnでdaisyUIをインストール
続いて、daisyuiを導入していきましょう。
docker-compose exec web yarn add daisyui
をターミナルで入力
package.json
にインストールできているか確認してみましょう。
{
"name": "app",
"private": "true",
"dependencies": {
"autoprefixer": "^10.4.14",
"daisyui": "^2.51.6",
"esbuild": "^0.17.19",
"postcss": "^8.4.23",
"tailwindcss": "^3.3.2"
},
"scripts": {
"build:css": "tailwindcss -i ./app/assets/stylesheets/application.tailwind.css -o ./app/assets/builds/application.css --minify",
"build": "esbuild app/javascript/*.* --bundle --sourcemap --outdir=app/assets/builds --public-path=assets"
}
}
package.jsonに追加できていることを確認できたら、tailwind.config.js
にplugins: [require("daisyui")]
を追記
module.exports = {
content: [
'./app/views/**/*.html.erb',
'./app/helpers/**/*.rb',
'./app/assets/stylesheets/**/*.css',
'./app/javascript/**/*.js'
],
plugins: [
require('daisyui')
]
}
config/manifest.js
を以下のように変更しておきます
//= link_tree ../images
//= link_tree ../builds
そして、ターミナルでdocker-compose exec web ./bin/dev
と入力すると、daisyUIのスタイルがあたっていると思います。
ちなみに
daisyUIには、いろいろテーマがありテーマに沿ったデザインに変更することができます。
→ https://daisyui.com/docs/themes/
例えば、bumblebee
にしたい場合は、下記のように変更することでできます。(他にも色々な方法があったはずです)
module.exports = {
content: [
'./app/views/**/*.html.erb',
'./app/helpers/**/*.rb',
'./app/assets/stylesheets/**/*.css',
'./app/javascript/**/*.js'
],
plugins: [
require('daisyui')
],
daisyui: {
themes: [
"bumblebee"
],
},
}
そして、docker-compose exec web ./bin/dev
と叩くことで、そのテーマに応じたデザインに変更されると思います。
<h1 class="text-3xl font-bold underline">
Hello world!
</h1>
<button class="bg-gray-900 hover:bg-gray-800 text-white rounded px-4 py-2">tailwind</button>
<button class="btn">daisyUI</button>
<button class="btn btn-secondary">btn btn-secondary</button>
補足
デザインを変更する度に./bin/devをしなければならず、手間になります。おそらく、その都度./bin/devを叩かなくてもいい方法があると思うのですが、知見のあるかたがいれば、ぜひコメント欄で教えていただけると嬉しいです。
ポイント
- 今回は、Dockerでnodeのバージョンを指定し、daisyUIを導入しました。
こちらに、いろいろなインストール方法があるので、参考にしてみてください。 - daisyUIを導入する際は、'gem
cssbundling-rails
、gem 'jsbundling-rails'
でtailwindを追加するようにしましょう。
さいごに
ここまで長々と書きましたが、あくまでもこの記事では一例であり、もっといい方法があるかもしれません。
至らぬ点もあるかと思いますので、修正点があれば何なりとお申し付けください🙇🏻♂️
ここまで見ていただき、ありがとうございました。
下記に、githubのURLを載せておきます。良ければ参考にしてみてください。