【Rails+Docker+AWS】開発環境構築から本番公開まで（1/3 開発環境構築編）

なんだか結構苦労したので、自分の整理のためにも記事におこしました。
初学者でポートフォリオをとりあえず公開したい方は参考になるかもしれません。

## 完成図
Ruby 2.5.1
Rails 5.2.0
MySQL 5.7
![qiita用のインフラ構成図.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/513214/64654abc-e78d-1bc9-26b0-cf5a4f0b2281.png)

全部で3記事あります。
（１）開発環境構築編（この記事）
（２）AWSコンソール画面編　https://qiita.com/obr-note/items/f897762b831b6f3c273c
（３）デプロイ編　https://qiita.com/obr-note/items/44290f2011ad09240129

## Dockerデスクトップのインストール
ご自身のMacへDockerをまだインストールしていない人は、Dockerデスクトップをインストールします。
https://www.docker.com/products/docker-desktop

### Docker立ち上げ
クジラのアイコンクリックして、dockerデスクトップを立ち上げます。起動には数分かかります。
![dockerdesktop.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/513214/7d865ad8-c684-d13d-460f-445c679a4449.png)

## ターミナル作業
開発環境の構築はこちらの記事をほとんど真似してやりました。
https://qiita.com/eighty8/items/0288ab9c127ddb683315

### ファイル構成
```
~/project/webapp
├── Dockerfile
├── Gemfile
├── Gemfile.lock
├── containers ── nginx
├                 ├── Dockerfile
├                 └── nginx.conf
├── docker-compose.yml
└── environments ── db.env
```
### フォルダ作成
```
$ mkdir -p ~/project/webapp
$ cd ~/project/webapp
$ mkdir -p containers/nginx
$ mkdir environments
```
### Dockerfile作成（app用）
```
$ vim Dockerfile
```

```
# Dockerfile
FROM ruby:2.5.1

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

RUN apt-get update && apt-get install -y curl apt-transport-https wget && \
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 && apt-get install -y yarn

RUN curl -sL https://deb.nodesource.com/setup_10.x | bash - \
        && apt-get install -y nodejs

RUN mkdir -p /var/www/webapp

WORKDIR /var/www/webapp

ADD Gemfile /var/www/webapp/Gemfile
ADD Gemfile.lock /var/www/webapp/Gemfile.lock

RUN gem install bundler
RUN bundle install

ADD . /var/www/webapp

RUN mkdir -p tmp/sockets
RUN mkdir -p tmp/pids
```
### Gemfile作成
```
$ cd ~/project/webapp
$ touch Gemfile.lock
$ vim Gemfile
```

```
# Gemfile
source 'https://rubygems.org'
gem 'rails', '5.2.0'
```
### Dockerfile作成（web用）
```
$ cd ~/project/webapp
$ vim containers/nginx/Dockerfile
```

```
# containers/nginx/Dockerfile
FROM nginx:1.15.8

RUN rm -f /etc/nginx/conf.d/*

ADD nginx.conf /etc/nginx/conf.d/webapp.conf

CMD /usr/sbin/nginx -g 'daemon off;' -c /etc/nginx/nginx.conf
```
### nginxの設定ファイル作成
```
$ cd ~/project/webapp
$ vim containers/nginx/nginx.conf
```

```
upstream puma {
  server unix:///var//www/webapp/tmp/sockets/puma.sock;
}

server {
  listen 80;
  server_name puma;

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

  location ~ ^/assets/ {
    root /var/www/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 / {
    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://puma;
  }
}
```
### データベース設定ファイル作成
```
$ cd ~/project/webapp
$ vim environments/db.env
```

```
MYSQL_ROOT_PASSWORD=db_root_password
MYSQL_USER=user_name
MYSQL_PASSWORD=user_password
```
### docker-composeファイル作成
```
$ cd ~/project/webapp
$ vim docker-compose.yml
```

```
version: "3"
services:
  app:
    build:
      context: .
    env_file:
      - ./environments/db.env
    command: bundle exec puma -C config/puma.rb
    volumes:
      - .:/var/www/webapp
      - public-data:/var/www/webapp/public
      - tmp-data:/var/www/webapp/tmp
      - log-data:/var/www/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:/var/www/webapp/public
      - tmp-data:/var/www/webapp/tmp
    ports:
      - 80:80
    depends_on:
      - app
volumes:
  public-data:
  tmp-data:
  log-data:
  db-data:
```
### Railsアプリの作成
Dockerデスクトップが立ち上がっている状態で、下記コマンドを実行します。

```
$ cd ~/project/webapp
$ docker-compose run --rm app rails new . --force --database=mysql --skip-bundle # 数分かかります
$ ls
```
見慣れたRailsのファイルが並んでいれば、Railsアプリ作成完了です。
![files.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/513214/6d8c553b-ac84-2c2d-5a21-294c507eb2d7.png)

### pumaの設定ファイル修正
```
$ cd ~/project/webapp
$ cp /dev/null config/puma.rb
$ vim config/puma.rb
```

```
threads_count = ENV.fetch("RAILES_MAX_THREADS") { 5 }.to_i
threads threads_count, threads_count
port ENV.fetch("PORT") { 3000 }
environment ENV.fetch("RAILES_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"
```
### データベース接続情報ファイル修正
```
$ cd ~/project/webapp
$ cp /dev/null config/database.yml
$ vim config/database.yml
```

```
default: &default
  adapter: mysql2
  encoding: utf8
  pool: <%= ENV.fetch("RAILES_MAX_THREADS") { 5 } %>
  username: <%= ENV.fetch("MYSQL_USER") { 'root' } %>
  password: <%= ENV.fetch("MYSQL_PASSWORD") { 'password' } %>
  host: db

development:
  <<: *default
  database: webapp_development

test:
  <<: *default
  database: webapp_test
```
### Dockerイメージのビルド
```
$ cd ~/project/webapp
$ docker-compose build # 数分かかります
$ docker images
```
webapp_appとwebapp_webのイメージが作成できていれば、イメージの作成は完了です。
![dockerimage.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/513214/abbdd83b-ea1d-4373-9e31-616731dba54a.png)

### Dockerコンテナの立ち上げ
```
$ cd ~/project/webapp
$ docker-compose up -d
$ docker-compose ps
```
webapp_appとwebapp_dbとwebapp_webのコンテナのStateがUpになっていれば、コンテナの立ち上げは成功です。
![dockerps.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/513214/dabb1385-583f-8536-bda9-c9ef525f7e31.png)

### データベースへアクセス権限付与
```
$ cd ~/project/webapp
$ vim db/grant_user.sql
```

```
GRANT ALL PRIVILEGES ON *.* TO 'user_name'@'%';
FLUSH PRIVILEGES;
```

```
$ docker-compose exec db mysql -u root -p -e"$(cat db/grant_user.sql)"
Enter password: db_root_password
$ docker-compose exec db mysql -u user_name -p -e"show grants;"
Enter password: user_password
```
### データベース作成
```
$ cd ~/project/webapp
$ docker-compose exec app rails db:create
```

## 開発環境構築完了
開発環境の構築は終わりです。Welcomeページを見てみましょう。
http://localhost

![yayRails.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/513214/a6e8ad7f-d3fe-32f7-9ce3-2ade4509da40.png)


あとは、好きなエディタ（VSCodeとか）で、~/project/webappを開いて、開発していきましょう！
![vscode.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/513214/9342c1ae-ad31-a86b-c0d1-f7748d4021ef.png)

## 簡単なCRUDアプリ作成
後ほど、本番環境の動作確認用に簡単なCRUDアプリを作成しておきます。

```
$ cd ~/project/webapp
$ docker-compose exec app rails g scaffold Post title:string contents:string
$ docker-compose exec app rails db:migrate
$ vim config/routes.rb
```

```
Rails.application.routes.draw do
  root 'posts#index' # 追記
  resources :posts
end
```

topページにアクセスして、画面が下記のようになっていれば、OKです。
http://localhost
![crud.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/513214/3cd38be9-28b2-7be8-40c3-c3315bbd5e30.png)

AWSコンソール画面編へ続く
https://qiita.com/obr-note/items/f897762b831b6f3c273c