【初めてのチーム開発②】Dockerで環境構築する

[前回](https://qiita.com/taiga_tech/items/7b6d5d7a0a4fd6d5d70d)からの続きです。
Docker+Rails+Vue+MySQLの開発環境を作ったので、その備忘録。
(※本記事は適宜編集します。)

#手順
1. 前準備
2. Dockerfile作成 (Rails, Vue)
3. docker-compose.yml作成
4. プロジェクト作成
5. 動作確認
6. GitHubにpush

#1. 前準備

・作業用ブランチ作成

```
$ git branch (→developブランチにいることを確認)
$ git checkout -b feature/docker-test

[この時点でのブランチの構造]
main
develop
 └── feature/docker-test   <- New!
```

・バージョン確認etc.

```
$ docker -v
Docker version 19.03.8, build afacb8b
$ docker-compose -v
docker-compose version 1.25.4, build 8d51620a
```

・最終的なディレクトリ構成はこちら。【[参考](https://qiita.com/Kyou13/items/be9cdc10c54d39cded15#%E7%92%B0%E5%A2%83%E6%A7%8B%E7%AF%89%E3%81%AE%E6%B5%81%E3%82%8C)】

```
[project_name]
├── api
│   ├── Dockerfile
│   ├── Gemfile
│   └── Gemfile.lock
├── docker-compose.yml
└── front
    ├── Dockerfile
    ├── ...
```

#2. Dockerfile作成
RailsとVueのDockerfileをそれぞれ作成していきます。

まずはディレクトリを作成。

```
(現在のディレクトリ： project_name)
$ mkdir api front
$ ls
api front
``` 

##2.1 Rails
RailsのDockerfileを作ります。
`$ touch api/Dockerfile`

```text:api/Dockerfile
FROM ruby:2.7.1

RUN apt-get update -qq && \
    apt-get install -y build-essential \ 
                       libpq-dev \        
                       nodejs \
   && rm -rf /var/lib/apt/lists/* 

RUN mkdir /app
ENV APP_ROOT /app
WORKDIR $APP_ROOT

ADD ./Gemfile $APP_ROOT/Gemfile
ADD ./Gemfile.lock $APP_ROOT/Gemfile.lock

RUN bundle install
```

このDockerfileは「Railsを含むGemfile」を別途必要とします。
そこでapi下にGemfile, および空のGemfile.lockを作成します。
`$ touch api/Gemfile`
`$ touch api/Gemfile.lock`

```text:api/Gemfile
source 'https://rubygems.org'
gem 'rails', '~> 6.0.3'
```

##2.2 Vue
次にVueのDockerfileを作ります。
`$ touch front/Dockerfile`

```text:front/Dockerfile
FROM node:12.18.3-alpine

ENV APP_HOME /app
RUN mkdir -p $APP_HOME
WORKDIR $APP_HOME

RUN apk update && npm install -g @vue/cli
```

#3. docker-compose.yml作成
次に、プロジェクトディレクトリ下にdocker-compose.ymlを作成します。

```text:docker-compose.yml
version: '3'

services:
  web:
    build: ./api
    command: bundle exec rails s -p 3000 -b '0.0.0.0'
    ports:
      - '3000:3000'
    depends_on:
      - db
    volumes:
      - ./api:/app
      - bundle:/usr/local/bundle
    tty: true
    stdin_open: true
  db:
    image: mysql:5.7
    volumes:
      - mysql_data:/var/lib/mysql/
    environment:
      MYSQL_ROOT_PASSWORD: password
    ports:
      - '3306:3306'
  front:
    build: ./front
    volumes:
      - ./front:/app
      - node_modules:/app/node_modules
    ports:
      - '8080:8080'
    tty: true
    stdin_open: true
    command: npm run serve

volumes:
  mysql_data:
  bundle:
  node_modules:
```

#4. プロジェクト作成
ここからが本番！
RailsプロジェクトとVueプロジェクトを順番に作っていきます。
Vueは`vue-cli`というものを使って、対話的に作成していきます。

##4-1. Rails

####Railsプロジェクト作成
まず`rails new`でRailsプロジェクトを作成。
apiディレクトリ下に、Railsのファイル群が作成されます。
※ 少し時間かかります。

```
$ docker-compose run web rails new . --force --database=mysql --api
```

####dockerイメージ更新
Gemfileが更新されたので、buildしてdockerイメージを更新しておきます。

```
$ docker-compose build
```
####database.ymlの修正
RailsのDB設定ファイル`api/config/database.yml`を修正します。
なお`(password)`はdocker-compose.ymlの環境変数`MYSQL_ROOT_PASSWORD`で指定したものを記述してください。

```text:api/config/database.yml
default: &default
  adapter: mysql2
  encoding: utf8mb4
  pool: <%= ENV.fetch("RAILS_MAX_THREADS") { 5 } %>
  username: root
  - password:
  + password: (password)
  - host: localhost
  + host: db
```

####DBの作成
```
$ docker-compose run web rails db:create
```

[追記] 上記コマンドでエラー発生→解決しました。

```text:自分の対応
$ docker-compose run web rails db:create → Access Denied エラー
$ docker-compose down --volumes
$ docker-compose up -d
$ docker-compose run web rails db:create → Errno::ENOENT エラー
$ docker-compose down
$ docker-compose run web rails db:create → 成功
Created database 'app_development'
Created database 'app_test'
```
参考：https://qiita.com/fujisawatk/items/80da801c7e2ac68e4887
…原因はvolume周り？ Dockerの理解がまだまだ十分ではないですね…(^_^;)

`$ docker-compose up -d`をしてみて、localhost:3000にアクセスし、正常に表示されれば成功です！

##4-2. Vue
vue-cliでVueプロジェクトを作成します。
コンテナ内に入り、vue-cliを使って対話的にVueプロジェクトを作成します。
※設定内容は一例です。

参考：https://qiita.com/Kyou13/items/be9cdc10c54d39cded15

```
$ docker-compose run front sh (←Vueコンテナでシェルを実行)
```

以下、設定内容です。

```
$ vue create .
# 現在のディレクトリ(/app)に作成するかの確認
? Generate project in current directory? (Y/n) Yes

# プリセットを使用するかどうか
? Please pick a preset: (Use arrow keys)
  Default ([Vue 2] babel, eslint)
  Default (Vue 3 Preview) ([Vue 3] babel, eslint)
❯ Manually select features # TypeScriptをインストールするためこちらを選択

# プロジェクトにインストールするライブラリの選択
? Check the features needed for your project:
 ◉ Choose Vue version #
 ◉ Babel
❯◉ TypeScript # TypeScriptをインストールする場合はこれを選択
 ◯ Progressive Web App (PWA) Support
 ◯ Router
 ◯ Vuex
 ◯ CSS Pre-processors
 ◉ Linter / Formatter
 ◯ Unit Testing
 ◯ E2E Testing

# Vueバージョンの選択
? Choose a version of Vue.js that you want to start the project with (Use arrow keys)
❯ 2.x
  3.x (Preview)

# Class styleを使用するかどうか。私はObject styleを使うため No
? Use class-style component syntax? (Y/n) No

# TypeScriptと一緒にbabelを使うか
? Use Babel alongside TypeScript (required for modern mode, auto-detected polyfills, transpiling JSX)? (Y/n) Yes

# LintとFormatterの設定に何を使うか
? Pick a linter / formatter config:
  ESLint with error prevention only
  ESLint + Airbnb config
  ESLint + Standard config
❯ ESLint + Prettier
  TSLint (deprecated)

# Lintの実行タイミング
? Pick additional lint features: (Press <space> to select, <a> to toggle all, <i> to invert selection)
❯◉ Lint on save # 保存時にLintを実行
 ◯ Lint and fix on commit (requires Git)

# Babel, ESLintなどの設定をどこに記述するか
? Where do you prefer placing config for Babel, ESLint, etc.? (Use arrow keys)
❯ In dedicated config files # 各設定ファイルにする
  In package.json

# 今回設定した内容をプリセットで保存するか。基本的にはプロジェクトを以降作成することはないため No
? Save this as a preset for future projects? No

# パッケージマネージャーに何を使うか
? Pick the package manager to use when installing dependencies: (Use arrow keys)
  Use Yarn
❯ Use NPM
```

インストール完了後、`Ctrl+D`でコンテナを停止します。
また`front/Dockerfile`を以下のように書き換えます。

```
FROM node:12.18.3-alpine

ENV APP_HOME /app
RUN mkdir -p $APP_HOME
WORKDIR $APP_HOME

RUN apk update      (変更)
COPY package.json . (追加)
RUN npm install     (追加)
```

#5. 動作確認
Rails
`localhost:3000`にアクセスし、「Yay! you are on Rails!」が表示されたら成功。
Vue
`localhost:8080`にアクセスし、
![スクリーンショット 2021-01-09 21.46.03.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1007663/df67231f-f4c7-60a2-300b-fa481bb233f6.png)
が表示されたら成功。

#6. GitHubにpush

```
$ git status
On branch feature/docker-test
nothing to commit, working tree clean
$ git push origin feature/docker-test
```

##参考記事
（本記事）
・[DockerでRails + Vue + MySQLの環境構築をする方法【2020/09最新版】](https://qiita.com/Kyou13/items/be9cdc10c54d39cded15)
・[Docker Rails Vue.js MySQL環境構築](https://qiita.com/yusuke_mrmt/items/5c71335e3fcba308b784)
・[開発環境をDockerに乗せる方法とメリットを3ステップで学ぶチュートリアル](https://qiita.com/KeitaMoromizato/items/ae1a57fc62b41b942d71)
・[【Mac】Dockerと開発環境の作り方](https://team-lab.github.io/skillup/step1/04b-docker.html)

（その他、チーム開発手法）
・[git develop, feature branch作成からmergeするまで　(自分用メモ)](https://qiita.com/Naoki206/items/e5520453f92dcd4274f1)
★[Githubでチーム開発するためのマニュアル](https://qiita.com/siida36/items/880d92559af9bd245c34)