virtulbox + vagrant + Docker + nginx + puma + MySQL Rails環境構築

#環境
windows10 HOME
virtulbox + vagrant
CentOS7
Docker 19.03.6
docker-compose 1.17.1
nginx 1.15.8
rails 5.2.4.1
ruby 2.5.1
MySQL 5.7

#Vagrantfile
ATOMでメニューバーPackages→Remot FTP→Toggleクリック

File→Add Project Folderクリック

vagrantfileが配置されてるフォルダを選択して編集

35行目のコメントアウトを外す

```
35  config.vm.network "private_network", ip: "192.168.33.10"'
```
#Dockerインストール
```
$ sudo yum install -y yum-utils
$ sudo yum-config-manager \
    --add-repo \
    https://download.docker.com/linux/centos/docker-ce.repo
$ sudo yum makecache fast
$ yum list docker-ce.x86_64  --showduplicates |sort -r
# 出てきたものから選ぶ
$ sudo yum install -y docker-ce.x86_64
```
#起動＆自動起動設定
```
$ sudo systemctl enable docker
$ sudo systemctl start docker
```
#Docker Compose
```
$ curl -L https://github.com/docker/compose/releases/download/1.12.0/docker-compose-`uname -s`-`uname -m` > docker-compose
$ sudo mv docker-compose /usr/local/bin/docker-compose
$ sudo chmod +x /usr/local/bin/docker-compose
```
```
$ sudo visudo
Defaults    secure_path = /sbin:/bin:/usr/sbin:/usr/bin
```
上記を下記に変更

```
Defaults    secure_path = /sbin:/bin:/usr/sbin:/usr/local/bin:/usr/bin
```
#バージョン確認

```
$ docker-compose --version
docker-compose version 1.12.0, build b31ff33
```
#dockerグループに入れる
```
# dockerグループがなかった場合
# sudo groupadd docker
$ sudo gpasswd -a $USER docker
$ sudo systemctl restart docker
$ exit
# ログインし直す
```
#ディレクトリ作成
作業ディレクトリ

```
$ sudo mkdir -p /var/webapp
$ sudo chown -R $USER:$USER /var/webapp
```
#Nginxコンテナディレクトリ

```
$ mkdir -p /var/webapp/containers/nginx
```
#環境変数用ディレクトリ

```
$ mkdir /var/webapp/environments
```
#コンテナ生成のための各ファイルを作成
以下は/var/webappで行う

Rails用Dockerfile

```
$ vim Dockerfile
FROM ruby:2.5.1

# リポジトリを更新し依存モジュールをインストール
RUN apt-get update -qq && \
    apt-get install -y build-essential \
                       nodejs

# ルート直下にwebappという名前で作業ディレクトリを作成（コンテナ内のアプリケーションディレクトリ）
RUN mkdir /webapp
WORKDIR /webapp

# ホストのGemfileとGemfile.lockをコンテナにコピー
ADD Gemfile /webapp/Gemfile
ADD Gemfile.lock /webapp/Gemfile.lock

# bundle installの実行
RUN bundle install

# ホストのアプリケーションディレクトリ内をすべてコンテナにコピー
ADD . /webapp

# puma.sockを配置するディレクトリを作成
RUN mkdir -p tmp/sockets
```
#Gemfile

```
$ vim Gemfile
source 'https://rubygems.org'
gem 'rails', '5.2.0'
```
#Gemfile.lock

```
$ touch Gemfile.lock
```
#Nginx用Dockerfile

```
$ vim containers/nginx/Dockerfile
FROM nginx:1.15.8

# インクルード用のディレクトリ内を削除
RUN rm -f /etc/nginx/conf.d/*

# Nginxの設定ファイルをコンテナにコピー
ADD nginx.conf /etc/nginx/conf.d/webapp.conf

# ビルド完了後にNginxを起動
CMD /usr/sbin/nginx -g 'daemon off;' -c /etc/nginx/nginx.conf
```
#Nginx設定ファイル

```
$ vim containers/nginx/nginx.conf
# プロキシ先の指定
# Nginxが受け取ったリクエストをバックエンドのpumaに送信
upstream webapp {
  # ソケット通信したいのでpuma.sockを指定
  server unix:///webapp/tmp/sockets/puma.sock;
}

server {
  listen 80;
  # ドメインもしくはIPを指定
  server_name 192.168.33.10;

  access_log /var/log/nginx/access.log;
  error_log  /var/log/nginx/error.log;

  # ドキュメントルートの指定
  root /webapp/public;

  client_max_body_size 100m;
  error_page 404             /404.html;
  error_page 505 502 503 504 /500.html;
  try_files  $uri/index.html $uri @webapp;
  keepalive_timeout 5;

  # リバースプロキシ関連の設定
  location @webapp {
    proxy_set_header X-Real-IP $remote_addr;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header Host $http_host;
    proxy_pass http://webapp;
  }
}
```
#DB接続用の情報ファイル

```
$ vim environments/db.env
MYSQL_ROOT_PASSWORD=任意のパスワード
MYSQL_USER=任意のユーザーネーム
MYSQL_PASSWORD=任意のパスワード
```
#docker-compose.yml

```
$ vim docker-compose.yml
version: '3'
services:
  app:
    build:
      context: .
    env_file:
      - ./environments/db.env
    command: bundle exec puma -C config/puma.rb
    volumes:
      - .:/webapp
      - public-data:/webapp/public
      - tmp-data:/webapp/tmp
      - log-data:/webapp/log
    depends_on:
      - db
  db:
    image: mysql:5.7
    env_file:
      - ./environments/db.env
    volumes:
      - db-data:/var/lib/mysql
  web:
    build:
      context: containers/nginx
    volumes:
      - public-data:/webapp/public
      - tmp-data:/webapp/tmp
    ports:
      - 80:80
    depends_on:
      - app
volumes:
  public-data:
  tmp-data:
  log-data:
  db-data:
```
#Railsプリケーションの生成と編集

```
$ docker-compose run --rm app rails new . --force --database=mysql --skip-bundle
```
権限の変更

```
$ sudo chown -R $USER:$USER .
```
puma.rbの編集

```
$ cp /dev/null config/puma.rb
$ vim config/puma.rb
threads_count = ENV.fetch("RAILS_MAX_THREADS") { 5 }.to_i
threads threads_count, threads_count
port        ENV.fetch("PORT") { 3000 }
environment ENV.fetch("RAILS_ENV") { "development" }
plugin :tmp_restart

app_root = File.expand_path("../..", __FILE__)
bind "unix://#{app_root}/tmp/sockets/puma.sock"

stdout_redirect "#{app_root}/log/puma.stdout.log", "#{app_root}/log/puma.stderr.log", true
```
#database.ymlの編集

```
$ cp /dev/null config/database.yml
$ vim config/database.yml
default: &default
  adapter: mysql2
  encoding: utf8
  pool: <%= ENV.fetch("RAILS_MAX_THREADS") { 5 } %>
  username: <%= ENV.fetch('MYSQL_USER') { '任意のユーザーネーム' } %>
  password: <%= ENV.fetch('MYSQL_PASSWORD') { '任意のパスワード' } %>
  host: db

development:
  <<: *default
  database: webapp_development

test:
  <<: *default
  database: webapp_test
```
#イメージのビルドとコンテナの起動

```
$ docker-compose build
```

ビルド終わったら作成できてるか確認

```
$ docker images
REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
webapp_web          latest              3aaeba382d2c        5 seconds ago       109MB
webapp_app          latest              b5378e4870b4        17 seconds ago      1.03GB
<none>              <none>              cff3bcfe8b56        2 minutes ago       990MB
mysql               5.7                 84164b03fa2e        3 days ago          456MB
nginx               1.15.8              f09fe80eb0e7        13 months ago       109MB
ruby                2.5.1               3c8181e703d2        16 months ago       869MB
```
#コンテナ起動

```
$ docker-compose up -d
```
コンテナ起動してるか確認

```
$ docker-compose ps
    Name                  Command               State          Ports
---------------------------------------------------------------------------
webapp_app_1   bundle exec puma -C config ...   Up
webapp_db_1    docker-entrypoint.sh mysqld      Up      3306/tcp, 33060/tcp
webapp_web_1   /bin/sh -c /usr/sbin/nginx ...   Up      0.0.0.0:80->80/tcp
```
#DB設定

権限の付与

```
$ vim db/grant_user.sql
GRANT ALL PRIVILEGES ON *.* TO '任意のユーザーネーム'@'%';
FLUSH PRIVILEGES;
```
ホストからdbコンテナに向けてクエリを流し込む

```
$ docker-compose exec db mysql -u root -p -e"$(cat db/grant_user.sql)"
```
権限が付与できたか確認

```
$ docker-compose exec db mysql -u 任意のユーザーネーム -p -e"show grants;"
+------------------------------------------------+
| Grants for user_name@%                         |
+------------------------------------------------+
| GRANT ALL PRIVILEGES ON *.* TO '任意のユーザーネーム'@'%' |
+------------------------------------------------+
```
#DB作成

```
$ docker-compose exec app rails db:create
```

#192.168.33.10へアクセスしてWelcomeページが表示できるか確認
![無題dwadwadwa-1024x909.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/409164/75e95b4f-c2b5-393b-17ea-77dcedfbbd00.png)

#コンテナ起動
```
$ docker-compose up -d
```
#実行中のコンテナを確認する
```
$ docker ps -a
CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS              PORTS                 NAMES
77a855c2588e        vagrant_web         "/bin/sh -c '/usr/sb…"   18 minutes ago      Up 18 minutes       0.0.0.0:80->80/tcp    vagrant_web_1
0fb43cede898        vagrant_app         "bundle exec puma -C…"   18 minutes ago      Up 18 minutes                             vagrant_app_1
b8f4fb3a8cc7        mysql:5.7           "docker-entrypoint.s…"   54 minutes ago      Up 54 minutes       3306/tcp, 33060/tcp   vagrant_db_1
```
#コンテナに入る
```
$ sudo docker exec -it 【CONTAINER ID】 bash
root@0fb43cede898:/webapp# 
```
#コンテナを指定してホストOS上でコマンドを実行する
```
docker exec -it 0fb43cede898 ruby --version
```