Docker + rails6 + MySQL + bootstrap,jqueryまで環境構築完全ロードマップ 

# はじめに

Docker + rails6 でポートフォリオを作成している途中でJqueryが必要になって追加している際に環境構築に失敗していることに気づいてかなり苦労したのでこれから始める方への手助けになればと思って書くことにしました。
また、Docker ＋ rails6 でbootstrap,jqueryについて触れながら実装されている情報が少なかったので、共有させていただきます。

### 環境

- Mac OS Catalina
- Ruby 2.7.2
- Rails 6.0.3.2
- MySQL 8.0
- bootstrap 4.5.3
- jquery 3.5.1



#前提条件
今回の投稿ではDocker desktopはインストール、Dockerに関しての基礎知識は省略して進めますのでまだDocker desktopをインストールされていない方は

[Macにdockerインストール](https://qiita.com/ama_keshi/items/b4c47a4aca5d48f2661c)
上記リンクからインストールをしてみてください。

基礎知識
[Dockerとはどういったものなのか、めちゃくちゃ丁寧に説明してみる]


# 手順

目次代わりにざっくりと手順を書いてから詳しくコードを書いていきたいと思いますので全部見る必要がない方は、部分的にピックアップして飛んでいただけたらと思います。

~アプリ準備編~
1. ディレクトリ(フォルダ)を新しく作成し、その中に必要なファイルを作成する。
2. rails newでアプリを新規作成し、イメージビルド
3. db設定修正してコンテナ立ち上げ

~補足情報(docker操作方法)~

~bootstrap,jquery追加編~
1. yarn でbootstrap,jquery,popper.js を追加
2. ファイルを追加,修正

このような内容で進めていきます。かなり長くなりそうですがご容赦ください。(なりました←)
それでは行きましょう！！

# ~アプリ準備編~

## 1.ディレクトリ(フォルダ)を新しく作成し、その中に必要なファイルを作成する。

今回はわかりやすいようにデスクトップに新しいディレクトリ(sample_app)を作成しましょう。(以下のコマンド)

```
$ mkdir sample_app
```

このディレクトリの中に
`Dockerfile 
docker-compose.yml
Gemfile
Gemfile.lock
entrypoint.sh
`
を作成します。

```
$ touch Dockerfile
$ touch docker-compose.yml 
...(以下省略)
```

そしてそのファイルの中に記述していきます。

 ```docker:Dockerfile
FROM ruby:2.7
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 -qq \
    && apt-get install -y nodejs yarn \
    && mkdir /app
WORKDIR /app
COPY Gemfile /app/Gemfile
COPY Gemfile.lock /app/Gemfile.lock
RUN bundle install
COPY . /app

# Add a script to be executed every time the container starts.
COPY entrypoint.sh /usr/bin/
RUN chmod +x /usr/bin/entrypoint.sh
ENTRYPOINT ["entrypoint.sh"]
EXPOSE 3000

# Start the main process.
CMD ["rails", "server", "-b", "0.0.0.0"]
```

```yml:docker-compose.yml
version: '3'
services:
  db:
    image: mysql:8.0
    volumes:
      - ./tmp/db:/var/lib/mysql
    environment:
      - MYSQL_ALLOW_EMPTY_PASSWORD=1
  web:
    build: .
    command: bash -c "rm -f tmp/pids/server.pid && bundle exec rails s -p 3000 -b '0.0.0.0'"
    volumes:
      - .:/app
    ports:
      - "3000:3000"
    depends_on:
      - db

```

```ruby:Gemfile

source 'https://rubygems.org'
gem 'rails', '~>6'
```

```ruby:Gemfile.lock
#何もしない
```

```sh:entrypoint.sh
#!/bin/bash
set -e

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

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

詳しい説明は省きますが、ここで大切なのは、Dockerfileの

```docker:Dockerfile
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 -qq \
    && apt-get install -y nodejs yarn \
    && mkdir /app
```


ここが後々bootstrap,jqueryを追加するときに重要になってくる要素になるので間違えずにコピペしてください。
(僕は最初個々の記述がない状態で進めたためにめちゃくちゃ無駄な悩みを抱えることになりました。。)

## 2. rails newでアプリを新規作成し、イメージビルド

### アプリ作成

これでアプリを作る準備ができたので早速アプリの枠組みをDocker内に作ってもらいましょう!

まずターミナルで以下のコマンドを入力したらdockerが勝手にアプリに必要なファイルを作ってくれます

```
$ docker-compose run web rails new . --force --no-deps --database=mysql --skip-test --webpacker
```


 今回はminitestではなくrspecを使うためにtestディレクトリは作らないという指定をしています。
(rails-tutorialをやっていた方でminitestを使いたい方は「--skip-test」を省略してください)

また、webpackerというのがbootstrap,jqueryに関係していくので忘れずに入力してください。

そして、約5分くらいdockerが頑張ってアプリを立ち上げるので、その間は絶対にターミナルを触らないようにしましょう。
最後にこの文が帰ってきたら成功です！！

```
Successfully built ~~~~~~~~
Successfully tagged アプリ名_web:latest
```



### イメージビルド

アプリ作成が完了してまたユーザーにターミナル入力権限が与えられたら次は

```
$ docker-compose build
```

を入力します。

これは、Gemfileを見てもらえればわかりますが、先ほど記述した時のGemfileとは中身が書き換えられているので、buildしなおさなければならないのです。
要するにGemfile に変更を加えるたびに「docker-compose build」をしないといけないんだなあ。位に分かっていれば問題ありません。

そしてまた5分くらい待ちましょう。(この時間が僕の休憩時間になることが多いです←)

## 3.db設定修正してコンテナ立ち上げ

次にdbの設定をしていきます。よくわからない操作が続きますが、最初は深く考えずにとりあえず真似して入力していきましょう。

```
$ docker-compose exec db bash
```

上記のコマンドを入力すると

```
root@1234567899#
↑ @の後ろの数字は適当に打ちました
```

と帰ってくるので、「#」に続いて

```
# mysql -u root
```

と入力するとmysqlを操作できます。
そして以下のコマンド(ALTER~)を入力すると必要な設定ができます。

```
mysql> ALTER USER 'root'@'%' IDENTIFIED WITH mysql_native_password BY '';
-- Query OK, 0 rows affected (0.02 sec)　　<= #このコマンドが帰ってきたら正解です。
```

これができたら

```
> exit
```

を二回入力すると元のターミナルに戻ることができます。

次はconfig/database.ymlの記述を編集すれば、設定完了です。
以下のように修正してください

```yml:config/database.yml
default: &default
  adapter: mysql2
  encoding: utf8mb4
  pool: <%= ENV.fetch("RAILS_MAX_THREADS") { 5 } %>
  username: root
  password:
  host: db  #<= ここを変更する(before:localhost)
```

そして最後に、データベースを作成します。

```
docker-compose run web rails db:create
```

これですべての準備が整ったので、次のコマンドでターミナルを立ち上げましょう。

```
$ docker-compose up
```

以下の文面が帰ってきたら成功です。

``` 
web_1 | => Booting Puma
web_1 | => Rails 6.0.3.4 application starting in development
...
...
web_1 | => Use Ctrl-C to stop
```

ブラウザでも確認してみましょう。
google-chromeならリロードボタンの横の検索バーで

```
http://localhost:3000
```

と入力すると

![ダウンロード.jfif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/870730/bd775a60-8789-ea65-9fbf-8e0cd47221a8.jpeg)

こんな画面が出てくるのでこれでブラウザ上でも正常に動いていることが確認できました。
ひとまずお疲れ様でした！！

## 補足情報(docker操作方法)


```
$ docker-compose up
```

を入力したあとの

```
web_1 | => ...
...
```
の出力は、コンテナを立ち上げている間はずっとブラウザでの処理をデバッグ出力してくれているので
新しいターミナルをもう一つ立ちあげることでほかの操作(rails consoleやrails g controller 等)をすることができます。

新しいターミナルを立ち上げるには、

```
アプリのターミナルの場合 => ⌘ + T 
VSCode の場合 　　　　　=> 右上の「+」ボタン
```
で開くことができます。

### railsの操作

アプリを作っていく中でcontrollerやmodelを作成していく際に、例えば

```
rails generate controller User 
```
のように記述するように書かれている記事がよく見かけますが、
上記の表現はPC上に環境構築した人が対象のコマンドになります。

Dockerで環境構築をして人は必ず

```
$ docker-compose run web rails generate ...
```

という風に前にdocker上で操作しているという記述を添えて必要があります。
最初はとりあえず

```
$ docker-compose run web 
```
をつけてから始めるということを覚えていただければと思います。

### 1回目の終了、2回目以降の作業開始、終了手順

コンテナを終了するときは先程の

```
web_1 | => ...
...
```
が表示されてるターミナルに戻って

```
ctrl + C
```
を入力すればコンテナは止まってブラウザでは見れなくなります。
しかし、コンテナは止まっているだけで完全に消えたわけではありません。

``` 
$ docker-compose ps
```

を入力すると、 

```
         Name                        Command               State           Ports         
-----------------------------------------------------------------------------------------
アプリ名_db_1    docker-entrypoint.sh mysqld      Up      3306/tcp, 33060/tcp   
アプリ名_web_1   entrypoint.sh bash -c rm - ...   Up      0.0.0.0:3000->3000/tcp
```
このようなのが帰ってくると思います。
作業を終了するときはこれも完全に消してからPCの電源を落としたほうが次以降再度立ち上げる際に楽になります。

そして、その完全に消去するコマンドは

```
$ docker-compose down
```
ですることができます。
これで撤収作業は終了です。

``` 
$ docker-compose ps
```

を再度入力すると、 

```
         Name                        Command               State           Ports         
-----------------------------------------------------------------------------------------
```

となって削除が確認できます。

#### 2回目以降の作業開始
その後再度作業を再開するときは

```
$ docker-compose up
```
を入力するだけで、また前回と同じ状態になってくれます。(dbのデータも消されません)
本当にすごい技術ですよね...！

#### 注意点

コンテナを立ち上げる際にすぐにターミナルを開いてコマンドを打とうとするとDocker desktop側の準備ができていないので
macbookの場合はタスクバー右上のクジラマークをクリックして

```
$ Docker Desktop is starting
```
が

```
$ Docker Desktop is runnning
```
となっていることを確認してから立ち上げるようにしてください。

#### 2回目以降の作業終了
そして終了は1回目同様に、コンテナを立ち上げたターミナルで

``` 
ctrl + C
```
からの

```
$ docker-compose down
```
で完了です。

# ~bootstrap,jquery追加編~
## 前提条件
ここでもyarnがmac内にすでにインストールされているということで話を進めますのでまず入っていない方は

[Xcodeの旧バージョンをインストールする方法](https://qiita.com/TsukasaHasegawa/items/0d7d5c2cf3a2b8ce8993)
[Homebrewのインストール](https://qiita.com/zaburo/items/29fe23c1ceb6056109fd)
[homebrewでyarnインストール](https://qiita.com/hiro266/items/fb1d37c180d6cbc696c8)

このあたりを参考にインストールから始めてください！

## 1. yarn でbootstrap,jquery,popper.js を追加
それでは、bootstrap,jqueryを追加していきましょう！
ここまで来ればあと少しなので頑張りましょう！

タイトル通り以下のコマンドでインストールします！

```ruby
$ yarn add bootstrap jquery popper.js @fortawesome/fontawesome-free

#このコマンドでは先ほど触れた　docker-compose run web rails　は書かないでください
```

## 2. ファイルを追加,修正

そもそも、bootstrapはjqueryと依存関係にあり、jqueryはjavascriptという言語の一部となります。
そしてrails6からはwebpackerというシステムでjavascriptのファイルを管理しているのです。
さらにwebpackerを使うにはDocker内にもyarn必要でそれを用意しているのがDockerfileのコマンドになるのです...!

(冒頭のDockerfileやアプリ立ち上げの際に重要ですと書いたのはこのためです)

ということでwebpackerとjavascriptのファイルに記入していきます。

`app/javascript/packs/application.js` を開いてそこに次のコードをコピペして下さい。

```javascript:app/javascript/packs/application.js
require("@rails/ujs").start()
require("turbolinks").start()
require("@rails/activestorage").start()
require("channels")
...
//この下を記入
require("bootstrap");
...

```
他の方の記事によるとこの記述をすると依存関係のおかげで同時に

```
require("jquery");
```

も記述したように振舞ってくれるそうです。

次はwebpackerの方です。

`config/webpack/environment.js`を以下のように書き換えてください。

```javascript:config/webpack/environment.js
const { environment } = require('@rails/webpacker')
var webpack = require('webpack');

environment.plugins.prepend(
    'Provide',
    new webpack.ProvidePlugin({
        $: 'jquery/src/jquery',
        jQuery: 'jquery/src/jquery',
        Popper: ['popper.js', 'default']
    })
)

module.exports = environment
```
以上でrails上でbootstrap,jqueryを使う基盤を作ることができました！

### Scss の設定

最後に、scssの設定もしておきましょう

app/javascriptの中に新しく`stylesheets`ディレクトリを作成し、その中に`applicition.scss`ファイルを新規作成します。

```
$ mkdir stylesheets
$ cd ~app/javascript/stylesheets
$ touch application.scss
```

そして`application.scss`の中に次のコードを記入します。

```scss:app/javascript/stylesheets/application.scss
@import 'bootstrap/scss/bootstrap';
```

そして、次はもう一度`app/javascript/packs/application.js`に追加コードを記入します。

```javascript:app/javascript/packs/application.js
...(中略)
require("bootstrap");
...
//以下を追加する
import "../stylesheets/application.scss";
```

これで設定は全て完了です！

あとはこの`application.scss`内でscssのコードを一括管理することができます。
(※こうは書きましたが何故か他の`.scss`ファイルにコードを書いても全ページに適応されてしまうのでそこはもう少し調べていきたいと思います、、)

これで本当の本当にセットアップ完了しました！
お疲れ様でした！！！！

# 最後に

最後まで読んでいただきありがとうございました！

環境構築は最初にやらないと始められないくせにめちゃくちゃ難しくて諦める人も少なくないそうです。

僕もまだrails,dockerの勉強を始めて2か月たたないくらいで微力ではありますが、
もしこれから始められる方が僕と同じ失敗をしないように残していますので、
ぜひ参考にしていただけるととてもうれしく思います。

もし同じようにやられてエラー等ありましたら僕の答えられる範囲でご回答していきたいと思います!

また、ご指摘ありましたら是非教えて頂きたいと思います。

それでは、素敵なRails lifeを！

# 参考
[【Rails】Rails 6.0 x Docker x MySQLで環境構築](https://qiita.com/nsy_13/items/9fbc929f173984c30b5d)
[【初めての環境構築】Windows10にRails6+MySQL8.0+Dockerな環境を作ってみた](https://qiita.com/Kiyo_Karl2/items/25fc1b9ccd9c10bacd0f)
[DockerでRailsチュートリアルのローカル開発環境構築 - WebpackでBootstrapとFont Awesomeを導入 -](https://qiita.com/naokit-dev/items/30bf299cb0d785f9fb2f)