もう逃げない。基礎から学ぶDocker入門 / Docker Composeを使ってRailsの環境を構築する（8/9）

## はじめに

今まで、全然理解できていなくて逃げてたDockerに関して、しっかり理解していこうと思います。

https://www.docker.com/

コレまで、便利なんだろうなと思いながらも、逃げてました。

なので、開発環境では使いこなせるスキルにまでは理解したいと思います。

あと、暗記してたDockerコマンドを１つ１つ理解していきます。

以下のような順番で勉強していきます。

- [Dockerの概要（1/9）](https://qiita.com/ryosuketter/items/d7833182dced67713d27)
- [Dockerの基本操作（イメージの作成, コンテナの起動, 停止, 削除）（2/9）
](https://qiita.com/ryosuketter/items/c53352f1143366d8b9a9)
- [Dockerの基本操作（ログの出力, コンテナの中でプロセスを実行する方法, 使用していない Docker オブジェクトの削除）（3/9）](https://qiita.com/ryosuketter/items/5fd73b7311175a691dfe)
- [Dockerfileを使用したサーバー構築（座学編）（4/9）](https://qiita.com/ryosuketter/items/d9c3420be7da586225e8)
- [Dockerfileを使用したサーバー構築（実践編）（5/9）](https://qiita.com/ryosuketter/items/716a4c5e49795d494600)
- [Docker Composeの概要（座学編）（6/9）](https://qiita.com/ryosuketter/items/104a4eb38f8824eb6de9)
- [Docker Composeのよく使う基本操作（7/9）](https://qiita.com/ryosuketter/items/8bbd2c60392f443cfe23)
- [Docker Composeを使ってRailsの環境を構築する（8/9）](https://qiita.com/ryosuketter/items/91cd107794c1cbe358c6) :point_left_tone1: 今ここ
- [Docker上に構築したRailsをHeroku（本番環境）にデプロイ（公開）する（9/9）](https://qiita.com/ryosuketter/items/e3e68ce6ec572dc8905e)

## Docker Composeを使ってRailsの環境を構築する

Railsを題材に、複数のアプリケーションを組み合わせた、実践的なサービスをDocker Composeを使って構築していきます。

### 流れ

- 1. Dockerfileの作成
- 2. 初期設定
- 3. Dockerを起動
- 4. 実際の開発時に使いそうな操作

### Dockerfileの作成

#### ディレクトリ構成

```
rails_docker/
　└ src/
  　└ Gemfile
docker-compose.yml
Dockerfile
```

- プロジェクト直下にDocker関連のファイルを置いてます
- Railsのソースコードはsrc配下に

Dockerfileを見てみます

```Dockerfile:Dockerfile
FROM ruby:2.7

# Yarnのレポジトリを有効化。レポジトリのGPGキーをcurlコマンドを使って取得する(debianはubuntuと互換性がある)
RUN curl -sS https://dl.yarnpkg.com/debian/pubkey.gpg | apt-key add -

# YarnのAPTパッケージレポジトリを自分のシステムに追加。teeコマンドを使って書き込み。
RUN echo "deb https://dl.yarnpkg.com/debian/ stable main" | tee /etc/apt/sources.list.d/yarn.list

# レポジトリがシステムに加えられたらパッケージリストをアップデートしてからYarnをインストールする
RUN apt-get update -qq
RUN apt-get install -y nodejs yarn

# Dockerコンテナ上の作業ディレクトリ
WORKDIR /app

# ローカル開発環境の./src配下の内容をDockerコンテナ上の/appにコピー
COPY ./src /app

# gemファイルのインストール
RUN bundle config --local set path 'vendor/bundle' && bundle install
```

https://qiita.com/deBroglieeeen/items/5c9b7341e95b142e0d56

```Gemfile:Gemfile
source "https://rubygems.org"

gem 'rails', ' ~> 6.1.0'
```

`rails new`で必要なファイルをごそってインストールできるので

```yml:docker-compose.yml
version: "3"
services:
  db:
    image: mysql:8.0
    command: --default-authentication-plugin=mysql_native_password
    volumes:
      - ./src/db/mysql_data:/var/lib/mysql
    environment:
      MYSQL_ROOT_PASSWORD: password
  web:
    build: .
    command: bundle exec rails s -p 3000 -b '0.0.0.0'
    volumes:
      - ./src:/app
    ports:
      - "3000:3000"
    depends_on:
      - db
```

`docker-compose.yml` では、2つのサービスを定義しています。

1つは、dbのサービス、もう1つは、webです。

#### db

dbはMySQL（8.0）、webの方はRailsを用意しています。

`volumes`はマウントする設定ファイルのパスを指定(mysqlのconfなど)。	

https://docs.docker.com/compose/compose-file/#short-syntax-3

`db`の場合、ローカル開発環境の`./src/db/mysql_data`の内容をDockerコンテナ上の`/var/lib/mysql`にマウントするという意味

`volume`として定義すると、データを永続的に持てるので、コンテナを作り直してもmデータを保管しておけます（開発が楽になります）。

`environment`環境変数に関する設定です。`MYSQL_ROOT_PASSWORD`という環境変数に`password`というものを入れています。

#### web

`build: .` ベースのイメージを同じディレクトリ内にある`Dockerfile`を参照するよという意味。

`command: ` はrailsでサーバを立ち上げる方ならお馴染みかもしれませんね。ポートは3000を指定していて、IPアドレスは全てを受け入れていますね。

`volumes` は、ローカル開発環境の`./src`以下の内容をDockerコンテナ上の`/app`にマウントするという意味

`ports` は、ローカル開発環境の`port: 3000`をDockerコンテナ上の`port: 3000`に接続するという意味

`depends_on` は、依存関係を表します。webはdbに依存するよという意味。これすると、接続の設定が楽になる。ここら辺が`Docker Compose`のいいところなのかもしれませんね。

----

この設定をしておくことで、コマンド一発で環境ができるので、楽ですね。

### 初期設定と作成

#### web

`rails new`して、railsの雛形を作りましょう

コマンドを実行したいので、`docker-compose run`を使います。

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

`docker-compose run`の後、 `web`とありますが、`docker-compose.yml`では、`services`が`web`と`db`があるので、どちらかを選ぶ必要があります。

実行後、railsの雛形が作成されます。

インストールが完了したら、新しいgemfileが作成されます。また、`src/`に大量のファイルが作られたことも確認できると思います。

Gemfileの内容が更新されたり、Dockerfile自体が更新されたら、再度、Dockerイメージをbuildする必要があります。

```bash
docker-compose build

[+] Building 464.5s (13/13) FINISHED
 => [internal] load build definition from Dockerfile                                                                                                                                                       0.1s
 => => transferring dockerfile: 32B                                                                                                                                                                        0.0s
 => [internal] load .dockerignore                                                                                                                                                                          0.0s
 => => transferring context: 2B                                                                                                                                                                            0.0s
 => [internal] load metadata for docker.io/library/ruby:2.7                                                                                                                                                3.0s
 => [1/8] FROM docker.io/library/ruby:2.7@sha256:29cb031943ce6279ad88af96a29f2843fc37e33c705b6d511e23326e8cad1592                                                                                          0.0s
 => [internal] load build context                                                                                                                                                                         29.1s
 => => transferring context: 218.84MB                                                                                                                                                                     29.0s
 => CACHED [2/8] RUN curl -sS https://dl.yarnpkg.com/debian/pubkey.gpg | apt-key add -                                                                                                                     0.0s
 => CACHED [3/8] RUN echo "deb https://dl.yarnpkg.com/debian/ stable main" | tee /etc/apt/sources.list.d/yarn.list                                                                                         0.0s
 => CACHED [4/8] RUN apt-get update -qq                                                                                                                                                                    0.0s
 => CACHED [5/8] RUN apt-get install -y nodejs yarn                                                                                                                                                        0.0s
 => CACHED [6/8] WORKDIR /app                                                                                                                                                                              0.0s
 => [7/8] COPY ./src /app                                                                                                                                                                                 17.1s
 => [8/8] RUN bundle config --local set path 'vendor/bundle' && bundle install                                                                                                                           389.8s
 => exporting to image                                                                                                                                                                                    24.9s
 => => exporting layers                                                                                                                                                                                   24.8s
 => => writing image sha256:b5758e167ecb8271025a90864e7863e1b2e58d945623dff7cd45f237b5ef7a87                                                                                                               0.0s
 => => naming to docker.io/library/rails_docker_web
```

これで、更新されたGemfileの内容を含んだDockerイメージが生成されました。

#### dbの設定

DBの設定をみていきます。

`rails_docker/src/config/database.yml`を見ていきましょう。

```yml:src/config/database.yml
...
username: root
password: password
host: localhost
...
```

まずは、passwordの設定（passwordと書くだけ）。

これは、`docker-compose.yml`のdb.environment.MYSQL_ROOT_PASSWORDと一致させる必要があります。

続いて、hostです。hostは、DBの接続先です。

```
host: localhost →　host: db
```

のように変更します。

これは、`docker-compose.yml`のdb.environment.web.depends_onの値と一致させることで、dbが使えるようになります。

#### dbの作成

```bash
docker-compose run web rails db:create

[+] Running 1/0
 ⠿ Container rails_docker_db_1  Running                                                                                                                                                                    0.0s
Created database 'app_development'
Created database 'app_test'
```

rails使う方にはお馴染みだと思いますが、railsを通じてDBの作成を行なっています。

Dockerのdbのコンテナを作成しても、まだDBは出来ていないので。

railsの環境設定に慣れている方であれば、それほど難しくなかったですね。

### Dockerを起動

初期設定が完了したので、起動させていきましょう。

```bash
docker-compose up
```

`docker-compose.yml`ファイルに、DBを作ったり、Railsのwebサーバを立ち上げたりするコマンドを書いたので、サーバが立ち上がるはずです。

`http://localhost:3000/`にアクセスして

いつもの

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/14191/3913e983-9421-4572-29b9-0935332d34e8.png)

が出れば、成功ですね。

:v_tone1::smiley::v_tone1:

### 実際の開発時に使いそうな操作

最後に、実際の開発に必要な追加操作を紹介します。

#### サーバの停止

```bash
docker-compose down
```

再度、立ち上げたいときは

```bash
docker-compose up -d
```

何度か説明してますが`-d`はデタッチドモード（裏側）で動いてくれます。

#### コンテナごとの状態などをリストで見たい時

```bash
docker-compose ps

NAME                 COMMAND                  SERVICE             STATUS              PORTS
rails_docker_db_1    "docker-entrypoint.s…"   db                  running             3306/tcp, 33060/tcp
rails_docker_web_1   "bundle exec rails s…"   web                 running             0.0.0.0:3000->3000/tcp, :::3000->3000/tcp
```

#### ログを見たい時

```bash
docker-compose logs
```

開発に詰まったら見ることもあると思います。

#### コマンドを実行したい時

```bash
docker-compose exec web /bin/bash
```

すると、webの方のコンテナ内でbashが使えるようになります。

#### DockerファイルやGemfileの修正を反映させたい場合

```bash
docker-compose build
```

これでイメージが作成されます。

次に

```bash
docker-compose up -d
```

で、コンテナが作成・起動します。

----

以上です。

## アウトプット100本ノック実施中

https://qiita.com/ryosuketter/items/713474dbd009870e4103