docker - docker-compose で [ Ruby on Rails + MySQL ] のローカル開発環境を作ってみた

## はじめに

Rails をローカルでお手軽に開発出来る環境を作りたくて情報を整備してみました。

## 概要

ホストOSの上に、Vagrant で操作する VirtualBox を導入し、その上に Docker / docker-compose が動作する CentOS を用意して、そこで Rails と MySQL が動作するようにします。

## システムの全体像

### システム構成

このコードは次のようなシステム構成において、Application Server にて実行されることを想定しています。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/79222/07d6cf8f-2f06-b37c-626c-6b311127df18.png)

### ソフトウェア・スタック

開発環境は次のようなソフトウェア・スタックです。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/79222/7e16ef3d-bda7-d87f-defb-b69245e6dd3a.png)

これらは以下のバージョン構成で動作確認しています。

|項目|内容|
|:--|:--|
|VirtualBox|5.2.22 r126460 (Qt5.6.3|
|Vagrant|Vagrant 2.2.0|
|CentOS|CentOS Linux release 7.6.1810 (Core)|
|Docker|Docker version 19.03.1, build 74b1e89|
|docker-compose|docker-compose version 1.17.1, build 6d101fb|
|Ruby|2.5.3|
|Ruby on Rails|Rails 5.2.2|
|bundler|Bundler version 2.0.2|
|MySQL|5.7|

## 手順

ここからが構築手順です。

### 0. 事前準備

Docker / docker-compose を自動でインストールする vagrant の起動スクリプトを用意してあるので、仮想環境の構築はこれを実行するだけです。

```bash:Command：ホストOSで実施

# Vagrant のプラグインをインストールする
vagrant plugin install vagrant-vbguest
vagrant plugin install vagrant-proxyconf

# GitHub から Vagrantfile と provision.sh を取得する
git clone https://github.com/anfangd/docker-on-vagrant-script.git

# 適当に名前を変えて カレントディレクトリ を変更
mv docker-on-vagrant-script centos-7-docker
cd centos-7-docker

# Vagrant の起動する
vagrant up

# 仮想環境へ ssh でアクセスする
vagrant ssh
```

起動した仮想環境内で、 Docker と docker-compose をコマンド操作できるか確認します。

```bash:Command：VirtualOSで実施
# docker の動作確認をする
docker run hello-world

# docker のバージョン確認をする
docker --version
Docker version 18.06.1-ce, build e68fc7a

# docker-compose のバージョン確認をする
docker-compose --version
docker-compose version 1.17.1, build 6d101fb
```

### １． 構築用スクリプトの取得

作業用のフォルダを作成し、GitHub からコンテナ構築用のスクリプトを取得します。

```bash:Command
# ホストOSと同期しているフォルダへ移動し、作業用フォルダを作成
cd /vagrant
mkdir workspace && cd &_

# docker-compose のスクリプトを取得し、適当なフォルダ名に変更
git clone https://github.com/anfangd/rails-by-docker-compose.git
mv rails-by-docker-compose rails-project
cd rails-project
```

取得したコードは次のような構成になっています。

```bash:Command
tree
├── docker-compose.yml
├── .env
├── mysql
│   ├── Dockerfile
│   ├── conf
│   │   └── etc
│   │      └── my.cnf
│   └── data
└── rails
    │── Dockerfile
    └── src
        │── Gemfile
        └── Gemfile.lock
```

### ２．初期プロジェクトの作成 と DBアクセス設定

次のコマンドで Rails のプロジェクトを新規作成します。

```
docker-compose run web rails new . --force --database=mysql --skip-bundle
```

`database.yml` を修正し、 Rails アプリケーションから DBホストへの接続情報を設定します。

```yml:rails/src/config/database.yml
default: &default
  adapter: mysql2
  encoding: utf8
  pool: <%= ENV.fetch("RAILS_MAX_THREADS") { 5 } %>
  username: root
  password: root
  host: db
```

### ３．スクリプトを実行してコンテナを起動

次のコマンドを実行して、Dockerコンテナを起動します。

```bash:Command
# ビルドする
docker-compose build

# 起動する
docker-compose up -d
```

### ４． マイグレーションの実施

Rails を使用してマイグレーションを実行します。

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

### ５．アクセス確認

次のURL へアクセスし、動作を確認します。

- http://hostname:13000

`hostname` は適切な値に変更します。

### ６．後始末

次のコマンドで環境を破棄します。

```bash:Command
docker-compose down
```


## 参考

### docker-compose の基本事項

- [docker-compose コマンドまとめ #Qiita](https://qiita.com/wasanx25/items/d47caf37b79e855af95f)
- [docker-compose up で tty: trueを付けているのに、commandを実行するとコンテナが終わってしまう - Stack Over Flow](https://ja.stackoverflow.com/questions/52132/docker-compose-up-%E3%81%A7-tty-true%E3%82%92%E4%BB%98%E3%81%91%E3%81%A6%E3%81%84%E3%82%8B%E3%81%AE%E3%81%AB-command%E3%82%92%E5%AE%9F%E8%A1%8C%E3%81%99%E3%82%8B%E3%81%A8%E3%82%B3%E3%83%B3%E3%83%86%E3%83%8A%E3%81%8C%E7%B5%82%E3%82%8F%E3%81%A3%E3%81%A6%E3%81%97%E3%81%BE%E3%81%86)

### Docker の デフォルト Network 名について

- [Compose のネットワーク機能 - Docker-docs-ja](http://docs.docker.jp/compose/networking.html)
- [docker-compose で複数環境を構築するときの設定をなるべく DRY に書く - ikasama over technology](https://ikasamak503.hatenablog.com/entry/dry-docker-compose-yaml)
- [いい加減docker-composeでlinksを使うのをやめてnetworkでコンテナ間名前解決をする #Qiita](https://qiita.com/dyoshikawa/items/05d627b962da35f7d5b6)

### Docker と docker-compose の環境変数について

- [Docker-Compose の変数定義について #Qiita](https://qiita.com/kimullaa/items/f556431b8103e686f356)

### docker-compose と MySQL

- [docker-compose＋MySQL5.7(8.0も)+初期化+永続化 #Qiita](https://qiita.com/juhn/items/274e44ee80354a39d872)
- [Docker 18.03でMySQL5.7コンテナ起動時に[File ./ib_logfile101: 'aio write' returned OS error 122.]メッセージが表示されたときの対処法](https://blog.tes.co.jp/entry/2018/07/09/100555)
- [【Windows】docker-composeを使ってmy.cnfの共有は気を付けよう！（🍣＝🍺問題など） #Qiita](https://qiita.com/koyo-miyamura/items/4d1430b9086c5d4a58a5)
- [MySQL5.6が起動しない時 #Qiita](https://qiita.com/nnmr/items/79400922df5810756bce)