④ローカルDocker環境でデータ永続化、entrypointでseed_fuをやり直しする(2020.4.時点)

#1.これからDocker導入します、という方は、まず、こちらを見ていただけると幸いです。

**[①Dockerを初めて導入して基本操作する (2020.4時点)](https://qiita.com/SakagamiKeisuke/items/4455631886b1c15a3b69)**

##前回までのおさらい　
**[③Docker MYSQLにデモデータ(seed_fu)を投入する!(2020.4時点)](https://qiita.com/SakagamiKeisuke/items/4ce1c4a4921abb57b896)**

前回、デモデータの投入ができて、アプリを起動から操作までできるようになりました。
あとはデータの永続化ができれば、一応、開発環境は整うのかなと思います。
データの永続化の作業過程でデモデータ投入ができなくなり、この解決までおこないます。

#2.前提
Docker for Macアプリをインストールしている
Dockerサービスが起動している
DockerHubでサインインしている
VSCodeで編集
ターミナル使用
Sequelpro使用(なくてもなんとかなります)

<環境>
macOS : Catalina 10.15.3
Docker version : 19.03.8
ruby : 2.5.1
Rails : 5.2.4.1
MYSQL :5.6

#3.データの永続化を設定する
Docker環境での開発作業の過程で、仮にDocker-compose downでコンテナを停止削除した場合、
コンテナのMYSQLイメージも、データベースも、保存していたデータも丸々消えてしまいます。
dbコンテナのMYSQLデータはどこかに退避させていないと、消失は不可避であります。

そこで、dbコンテナのMYSQLデータを、ローカルで指定するフォルダにマウント（同期・コピー）させてデータを退避させます。

参考にさせていただいた記事です（ありがとうございます！）
**Dockerのデータを永続化！Data Volume（データボリューム）の理解から始める環境構築入門**
https://nishinatoshiharu.com/docker-volume-tutorial/

#4.ローカルディレクトリとコンテナディレクトリを同期させマウントする
ローカルに 「 mysql 」フォルダを新規作成します。
命名は、わかりやすい名前なら何でもいいと思います。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/617331/3c074605-0edc-b448-937a-7863e7186116.png)

docker-compose.ymlのdbコンテナのvolumesに、
**ローカルのディレクトリ（./mysql）:  コンテナのディレクトリ（/var/lib/mysql  ）とマウント（同期）の記述します。**


```ruby:docker-compose.yml
  db:
    image: mysql:5.6
    volumes:
        
      - ./mysql:/var/lib/mysql     ←この記述を追加します

```
こんな感じです。
左側のローカルmysqlフォルダと、コンテナのMYSQLディレクトリと同期させたいわけです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/617331/53e0ee85-17ef-7d27-0ff5-b4d898697b76.png)
既にRails sで起動させていたコンテナとイメージを停止削除して、再起動します。

参考にさせていただいた記事（ありがとうございます！）
docker-compose コマンドまとめhttps://qiita.com/wasanx25/items/d47caf37b79e855af95f

コマンド　docker-compose down --rmi all 　を実行します。

```ruby:ターミナル 
docker-compose down --rmi all
```
こんな感じになります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/617331/76f83800-d644-1022-b65f-82702b6dd158.png)
停止削除できたようなので、コマンド　docker-compose up 　を実行します。


```ruby:ターミナル 
docker-compose up
```
こんな感じになります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/617331/4a53d886-734f-4be5-459e-a7302ee504f1.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/617331/d0588062-1bab-e08d-1454-a506573aa6c0.png)
これで、コンテナのイメージができ上がり、Rails sできました。

localhost:3000にアクセスするとこんな感じです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/617331/b4569695-6d94-7032-abcf-386e9a9ed82d.png)
データベースがありません、と怒られました。


データベース作成と、マイグレーション（テーブル作成）を実行します。

```ruby:ターミナル 
docker-compose run web bundle exec rake db:create  (データベース作成)

docker-compose run web bundle exec rake db:migrate  (テーブル作成)
```
こんな感じです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/617331/c3885b2d-e126-f6ea-d387-c836d82e0548.png)
もう一度、docker-compose up　で起動をかけます。

```ruby:ターミナル 
docker-compose up
```
再起動できました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/617331/098e4317-8773-711a-230d-cde7f9b41de8.png)


本題に戻ります。
ローカルで新規作成した「空っぽのmysqlフォルダ」の中にファイルやデータが勝手に作られています。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/617331/333dbd15-82d3-2107-8d6f-6c0397f24210.png)

ローカルのmsqlファイルの中を確認します。
（VSCodeで見ることもできます）

```ruby:ターミナル 
user@keisukeagamiAir nomadcafe  %  ls mysql  (cd でアプリディレクトリに移動しておきます)
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/617331/f33200be-248e-0d61-e510-d414678e15b5.png)

DockerコンテナのdbイメージのMYSQLの中を確認するため、コンテナIDを表示します。

```ruby:ターミナル 
docker ps
```
こんな感じです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/617331/83063a38-7f4b-ff5c-3ff5-dc7fa45802d0.png)
dbのコンテナにアクセスします。

```ruby:ターミナル 
docker exec -i -t bc10d5671842 bash
```
dbコンテナのMYSQLディレクトリの中を確認します。

```ruby:ターミナル 
 ls /var/lib/mysql
```
こんな感じです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/617331/f086a936-5f40-fad1-5fbc-15df72a47077.png)
ちなみに、こちらのコマンドでも同じ表示ができます。

```ruby:ターミナル 
docker-compose exec db ls /var/lib/mysql
```
こんな感じです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/617331/679aa28f-69a4-a379-8e9d-a85637cca0ba.png)
ローカルMYSQLと、コンテナMYSQLイメージの中身が同じであることがわかりました。
これで同期（マウント）ができました。


確認のために再起動します。

```ruby:ターミナル 
docker-compose down --rmi all 

docker-compose up 
```
結果、
前回ユーザー登録していたデータが永続化できたようで、その登録ユーザー情報でサインインできました！

#5.Dockerfile  entrypoint を使ったデモデータ投入（seed_fu実行）をする
③Docker MYSQLにデモデータ(seed_fu)を投入する!(2020.4時点)
https://qiita.com/SakagamiKeisuke/items/4ce1c4a4921abb57b896

docker-compose.ymlファイルでdb:seed_fuコマンドを指定していました。

```ruby:docker-compose.yml
command: bash -c "bundle exec rake db:seed_fu && /bin/bash"
```


しかし、これが実行しなくなりました
（汗）
当方、理解度不足で、原因がわかりませんので、正攻法？でseed_fuを実装し直します。


#6. entrypoint.sh を新規作成して編集する
ローカルで、entrypoint.shファイルを新規作成して編集します。
シェルスクリプトを用いて記述します。

こんな感じです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/617331/bf792206-75f1-b551-78b0-e5917d682f5c.png)
##DokerfileにENTRYPOINTを記述する

1. ローカルで新規作成したentrypoint.shをコンテナのentrypoint.shファイルにコピーする
2. chmod（チェンジモード）コマンド（a）全てを対象に(x)実行権限を付与します
3. entrypoint.shを参照し、ENTRYPOINTを実行します

chmod（チェンジモード）コマンドはUNIX系オペレーティングシステムにおけるシェルコマンドで、
Linuxなどでシェルスクリプトを書いた時は、実行可能権をつけていないと実行できないとのこと。
**<管理権限>　　r ･･･ 読み込み　w ･･･ 書き込み　　x ･･･ 実行**
**<権限対象>　　u ･･･ 所有者　　g ･･･ グループ　　o ･･･ その他　a ･･･ 上の3つ全て**

Dockerfile に以下を記述します。
（当方は、これを全部書くことで実行がうまくできました。）

```ruby:Dockerfile
COPY ./entrypoint.sh /
RUN chmod a+x /entrypoint.sh
ENTRYPOINT ["/entrypoint.sh"]
```
こんな感じです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/617331/9c4148fe-1d68-1112-d128-35c895dd838d.png)

#7.docker-compose.yml を修正
前回の記事
③Docker MYSQLにデモデータ(seed_fu)を投入する!(2020.4時点)
で記述していたコード
docker-compose.yml で command: 指定していたsee_fuは不要ですので削除します。

```ruby:docker-compose.yml
command: bash -c "bundle exec rake db:seed_fu && /bin/bash”     ←削除
```
こんな感じです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/617331/11ccd7e9-ac00-ae20-5d63-2bb5d6fdeccd.png)
再起動をかけます。

```ruby:ターミナル 
docker-compose down --rmi all    コンテナとイメージを停止削除

docker-compose up           イメージ構築、コンテナ構築、コンテナ起動

```
こんな感じです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/617331/59e846c2-d83a-9789-6779-902ed366187d.png)
db:seed_fuが実行されてます！デモデータが見える。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/617331/bdd151fe-8994-832a-8ef5-b441cac3e348.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/617331/035970b1-962f-0393-bf6a-dc049725f325.png)
Localhost:3000にアクセスします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/617331/9ec9a7d8-e2b6-7240-1a94-dbe44c39f7dd.png)
　デモデータが反映されてます！

これで、
**[①Dockerを初めて導入して基本操作する (2020.4時点)](https://qiita.com/SakagamiKeisuke/items/4455631886b1c15a3b69)**
**[②Dockerを初めて導入してRails sする (2020.4時点)](https://qiita.com/SakagamiKeisuke/items/d64ee54c22378223659a)**
**[③Docker MYSQLにデモデータ(seed_fu)を投入する!(2020.4時点)](https://qiita.com/SakagamiKeisuke/items/4ce1c4a4921abb57b896)**
**[④ローカルDocker環境でデータ永続化、entrypointでseed_fuをやり直しする(2020.4.時点)](https://qiita.com/SakagamiKeisuke/items/8d3fc70a2939cd4bbe3e)**

ができ、ローカルのDocker環境でアプリ開発できる準備が整いました！

#8.最後に

当方、
実務未経験＋初学者＋テッ○キャンプ卒業＋転職活動中であります。

このDocker実装の内容は実戦的ではない、足りない部分や無駄があるかと思います。
しかし、ゼロスタートからDockerやってみたい！という方には参考になると信じています。

この先も、本番環境でのdocker実装を進めつつ、その過程をわかりやすい記事で寄稿していきたいと考えています。
**[⑤AWS仮想サーバを利用する、AWSアカウント作成 + EC2インスタンス作成(2020.4時点)](https://qiita.com/SakagamiKeisuke/items/9568754f318edd53e39d)**

参考書ではRailsに実装はできそうになく、公式リファレンスを読んでも当然いきなりコードは書けず、たくさんの先輩方の記事投稿のおかげで、読み合わせ解読してDockerの実装ができました。
本当にありがとうございました！