docker-compose+Rails+Mysqlでサーバー起動まで

##はじめに 
Dockerを使って開発演習が出来たことに感動したので、その嬉しさの勢いと、アウトプットとして書きます。また、Dockerの仕組みが分からなくても、以下に従っていけば、とりあえず構築できます。 
##環境
+ Docker for Windows
+ VScode 
+ Windows10 Pro 
+ Mysql 

Windowsを使ってますが、基本的にmacの方も、DockerとMysqlがインストールされていれば大丈夫です。 

Dockerがインストールされているかの確認 

``` 
docker --version 
Docker version 18.09.1, build 4c52b90 
``` 

##Dockerの起動 
デスクトップにあるクジラのアイコンをクリックすると、起動します。右下のバーにクジラアイコンがあれば、Dockerが起動しています。 

![images.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/406548/a2f1529e-dbbf-4941-a077-c0c306f70ecb.png)


 

##Railsアプリ用のディレクトリを作成 
例えば現在のディレクトリがrailsというディレクトリだとします。 

``` 
$ pwd 
/rails 
``` 
そして、これから作成するアプリ用のディレクトリを以下のように作り、そこに移動します。ここでは、ディレクトリ名をdocker_sample_appとします。 

``` 
$ mkdir docker_sample_app 
$ cd docker_sample_app 
$ pwd 
  /rails/docker_sample_app
``` 
##Dockerファイルなどの準備 
以下の4つのファイルを作成してください。 

``` 
$ touch docker-compose.yml Dockerfile Gemfile Gemfile.lock 
``` 
そして、VScode内でファイルを変更していきます。 



```docker-compose.yml 
version: '3'
services:
  db:
    image: mysql:5.7
    ports:
      - "3306:3306"
    restart: always
    environment:
      - MYSQL_DATABASE=app_name_db
      - MYSQL_ROOT_PASSWORD=password
    volumes:
      - ./data:/var/lib/mysql:rw
    command: --innodb_use_native_aio=0
  web:
    build: .
    command: bundle exec rails s -p 3000 -b '0.0.0.0'
    volumes:
      - .:/app_name
    ports:
      - "3000:3000"
    depends_on:
      - db
    environment:
      DB_HOST: db
``` 


```Dockerfile.
FROM ruby:2.5.3
ENV LANG C.UTF-8
RUN apt-get update -qq && apt-get install -y build-essential libpq-dev nodejs
RUN gem install bundler
WORKDIR /tmp
ADD Gemfile Gemfile
ADD Gemfile.lock Gemfile.lock
RUN bundle install
ENV APP_HOME /app_name
RUN mkdir -p $APP_HOME
WORKDIR $APP_HOME
ADD . $APP_HOME
``` 

docker-compose.ymlは上から9, 18行目のapp_nameを、Docker.fileは下から4行目の箇所を、先ほど作成したディレクトリ名に変えてください。(ここではdocker_sample_app) 

docker-compose.yml内にportが二つあります。db側はmysql workbenchからアクセスするためのポートで、web側はブラウザでlocalhostでアクセスするためのものです。
正直workbenchは今回のサーバ起動までという目的には含まれてないので、気にしなくて大丈夫です。



```Gemfile.
source 'https://rubygems.org' 
gem 'rails' 
``` 

Gemfile.lockは空で問題ないです。
 
##Railsアプリの作成
ターミナルで、このコマンドをうってください。 

``` 
$ docker-compose run web rails new . -d mysql --skip-bundle 
``` 
途中で 

``` 
Overwrite /docker_sample_app/Gemfile? (enter "h" for help) [Ynaqdhm] 
``` 
と聞かれます。そこは、「y」とタイプしてください。 すると、ディレクトリ内にrails newした時と同じようなファイルが作成されているのが分かると思います。 次に、プロジェクトをビルドします。
 
``` 
$ docker-compose build 
``` 
このコマンドでDockerfileの内容が実行されます。 おめでとうございます。あと、もうすこしです。 
##サーバーを立ち上げる 

以下のコマンドをうつことで、サーバーを立ち上げれます。 

```
$ docker-compose up -d
```
この状態でブラウザに行って、localhostにアクセスしようとすると、 

```
Can't connect to local MySQL server through socket '/var/run/mysqld/mysqld.sock' (2 "No such file or directory") 
``` 
といったエラーが出ると思います。これは、まだdatabaseファイルを設定していないからです。なので、変更してあげます。

```database.yml 
default: &default
  adapter: mysql2
  encoding: utf8
  pool: <%= ENV.fetch("RAILS_MAX_THREADS") { 5 } %>
  username: root
  password: password
  host: <%= ENV['DB_HOST'] %>
development:
  <<: *default
  database: app_name_development
test:
  <<: *default
  database: app_name_test

``` 
今回は、本番環境を用意する必要ではないので、Productionは消しました。先ほどと同じように、app_nameをディレクトリ名(docker_sample_app_developmentのように)に変更してください。  

そしたら、データベースファイルをいじったので、サーバーを再起動します。

```
$ docker-compose down
$ docker-compose up -d
```

そして、ブラウザをリロードすると、違うエラーが出ます。

```
Unknown database 'app_name_development'
```

これは、「データベースを作成してください」というエラーなので、言われるがままにデータベースを作りましょう。

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

ブラウザに戻ってください。localhost:3000にアクセスすると無事、例の画面が出るはずです！！！

<img width="600" alt="20190427151753.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/406548/29b6be26-d9a2-1b7b-d1ff-c0733332f062.png">


これで今回の目標は達成されました！

##docker-composeのコマンドについて
rails c, rails db:createなどのコマンドがありますが、docker-composeを使うときは、以下のコマンドを必ずその前に付けなければなりません。

```
docker-compose exec web 
```

なので、例えば、データベースを作りたい時は

```
docker-compose exec web rails db:create
```
となります！

ちなみにrails sコマンドは使いません。
docker-compose up -dでサーバが起動するからです。

###[番外編]

ルーティングファイルなどを変更したらサーバーを再起動させますが、viewsファイルに関しては変更してもサーバの再起動は、必要ないのですが、反映されないことが分かりました。その場合は、development.rbファイルを変更する必要があることが分かりました。


```development.rb
config.file_watcher = ActiveSupport::EventedFileUpdateChecker
```
のEventedFileUpdateCheckerのところをFileUpdateCheckerに変更します。

```development.rb
config.file_watcher = ActiveSupport::FileUpdateChecker
```

##参考にさせていただいた記事
[dockerでrails5環境構築](https://qiita.com/pocari/items/456052a291381895f8b3#%E5%9B%B0%E3%81%A3%E3%81%9F%E7%82%B9:embed:cite)