【初学者】はじめてのDockerを使った環境構築【Docker + Rails7.1.2 + esbuild + Node.js 20.5.1 + Tailwind CSS + daisyUI + PostgreSQL】

# はじめに
お疲れさまです！
おおくまです！

今回、はじめて``Docker``を使って環境構築をやってみました！
技術選定としては、
**Docker + Rails7.1.2 + esbuild + Node.js 20.5.1 + Tailwind CSS + daisyUI + PostgreSQL**
こんな感じです！
また、サーバーを立ち上げる際は、
``./bin/dev``のコマンドを使い、
**JSやCSSがビルドされ、なおかつJSやCSSを変更したときに自動的に再ビルドされる**ようにします！
備忘録として残したいと思います！

# 注意点
:::note warn
私はプログラミング学習中で、初学者です。
内容に誤りがある場合があります。
コメント等で教えていただけると幸甚です。
:::

# 環境
:::note
Ruby 3.2.2
Rails 7.1.2
Node.js 20.5.1
Docker Desktopをインストール済み
:::


# 手順
```:ターミナル
mkdir test_app
cd test_app
touch Dockerfile Gemfile Gemfile.lock docker-compose.yml entrypoint.sh
```
まずは、``test_app``という作業ディレクトリを作成します！
その中に、``Docker``の環境構築で使用する5つのファイルを作成します！

<br>

それぞれにコードを書いていきます！

<br>

```diff_ruby:Dockerfile
FROM ruby:3.2.2

ENV TZ Asia/Tokyo

RUN apt-get update -qq && apt-get install -y build-essential libpq-dev nodejs && apt-get install -y vim

RUN curl -sL https://deb.nodesource.com/setup_20.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 /test_app

COPY Gemfile Gemfile.lock /test_app/

RUN bundle install

COPY . /test_app/

COPY entrypoint.sh /usr/bin/

RUN chmod +x /usr/bin/entrypoint.sh

ENTRYPOINT ["entrypoint.sh"]

CMD ["./bin/dev"]
```

<br>

```diff_ruby:docker-compose.yml
services:
  db:
    image: postgres
    environment:
      POSTGRES_USER: user
      POSTGRES_PASSWORD: password
    volumes:
      - postgres_volume:/var/lib/postgresql/data
    ports:
      - '5432:5432'
  app:
    build:
      context: .
      dockerfile: Dockerfile
    command: sh -c "rm -f tmp/pids/server.pid && bundle exec rails s -p 3000 -b 0.0.0.0 && ./bin/dev"
    volumes:
      - .:/test_app
    ports:
      - 3000:3000
    stdin_open: true
    tty: true
    depends_on:
      - db
volumes:
  postgres_volume:
```

<br>

```diff_ruby:entrypoint.sh
#!/bin/bash

set -e

rm -f /test_app/tmp/pids/server.pid

exec "$@"
```

<br>

```diff_ruby:Gemfile
source "https://rubygems.org"
gem "rails", "~> 7.1.2"
```

<br>

```diff_ruby:Gemfile.lock
# ここには何も書かない
```

<br>

```:ターミナル
docker-compose run --rm app rails new . --force --database=postgresql --javascript=esbuild --css=tailwind --skip-docker
```
``Docker Desktop``を立ち上げた状態で、上記のコマンドで``rails new``します！
``Rails7.1系``は、``rails new``した際に、自動的に本番用の``Dockerfile``が作成されるようになっています！
``--skip-docker``オプションを付けることで、``Dockerfile``が上書きされてしまうのを防ぎます！

<br>

``rails new``が完了したら、再度、ファイルを編集していきます！

<br>

```diff_ruby:config/database.yml
default: &default
  adapter: postgresql
  encoding: unicode
  host: db
  username: user
  password: password
  pool: <%= ENV.fetch("RAILS_MAX_THREADS") { 5 } %>

development:
  <<: *default
  database: test_app_development

test:
  <<: *default
  database: test_app_test

production:
  <<: *default
  url: <%= ENV['DATABASE_URL'] %>
```

<br>

```diff_ruby:compose.yaml
services:
  db:
    image: postgres
    environment:
      POSTGRES_USER: user
      POSTGRES_PASSWORD: password
    volumes:
      - postgres_volume:/var/lib/postgresql/data
    ports:
      - '5432:5432'
  app:
    build:
      context: .
      dockerfile: Dockerfile
    command: sh -c "rm -f tmp/pids/server.pid && ./bin/dev"
    volumes:
      - .:/test_app
+     - node_modules:/test_app/node_modules
    ports:
      - 3000:3000
    stdin_open: true
    tty: true
    depends_on:
      - db
volumes:
  postgres_volume:
+ node_modules:
```

<br>

```diff_ruby:tailwind.config.js
module.exports = {
  content: [
    './app/views/**/*.html.erb',
    './app/helpers/**/*.rb',
    './app/assets/stylesheets/**/*.css',
    './app/javascript/**/*.js'
  ],
+ plugins: [require("daisyui")],
}
```

<br>

```diff_ruby:Dockerfile
FROM ruby:3.2.2

ENV TZ Asia/Tokyo

RUN apt-get update -qq && apt-get install -y build-essential libpq-dev nodejs && apt-get install -y vim

RUN curl -sL https://deb.nodesource.com/setup_20.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 /test_app

COPY Gemfile Gemfile.lock /test_app/

RUN bundle install

+ COPY package.json yarn.lock /test_app/

+ RUN yarn install

+ RUN yarn add daisyui

COPY . /test_app/

COPY entrypoint.sh /usr/bin/

RUN chmod +x /usr/bin/entrypoint.sh

ENTRYPOINT ["entrypoint.sh"]

CMD ["./bin/dev"]
```

<br>

```diff_ruby:Procfile.dev
app: env RUBY_DEBUG_OPEN=true bin/rails server
js: yarn build --watch
css: yarn build:css --watch
```
<br>

```:ターミナル
docker-compose up -d --build
docker compose exec app rails db:prepare
```
上記のコマンドで、再度ビルドし、データベースをセットアップすれば、環境構築は終了です！

<br>

``Tailwind CSS``と``daisyUI``がきちんと反映されるか確認していきましょう！

<br>

```:ターミナル
docker-compose exec app rails g controller Tops index
```

<br>

```diff_ruby:route.rb
Rails.application.routes.draw do
  root "tops#index"
end
```

<br>

```diff_ruby:index.html.erb
<h1 class="text-5xl font-bold underline py-5">
    Hello world!
</h1>

<button class="bg-gray-900 hover:bg-gray-800 text-white rounded px-4 py-2">tailwind</button>

<button class="btn btn-primary">daisyUI</button>
```

<br>

``http://localhost:3000/``にアクセスし、
<img width=800 src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3348444/4858027b-e0f3-8425-acf2-9e0b20c3cc95.jpeg">
このように表示されていればOKです！

<br>

```md:README.md
# セットアップ<br>
## docker compose up -d --build<br>
## docker compose exec app rails db:prepare<br>
```
最後に、``README.md``にセットアップ手順を記入して終了です！

# さいごに
本記事が何かのお役に立てれば幸甚です！
最後まで読んでいただきありがとうございました！

# 参考記事

https://qiita.com/ICU1234/items/4c7c3e974ae290e68792

https://qiita.com/mikaku/items/9ac2079b5ed292ec936d

https://qiita.com/P-man_Brown/items/c2a69d943853cb381fbe