LoginSignup
12
6

More than 3 years have passed since last update.

初心者がDockerで開発環境構築してみた(Rails&MySQL)

Last updated at Posted at 2020-07-23

はじめに

現在、就職活動中のプログラミング初学者です。
開発環境にDockerを取り入れる為、いろいろ勉強して自分用のメモとしてまとめておりましたが、折角なら同じ初学者の方の役に立てればと思い投稿させて頂きます。既に多くの方がDockerの環境構築に関する記事を書かれており、そういった記事を参考にさせて頂きながら、メモとしてまとめていましたので、内容はそんなに目新しものではありません。予めご了承ください。また、誤った表現などがありましたらご指摘頂けると幸いです。

開発環境

  • Ruby 2.6.3
  • Rails 5.2.3
  • MySQL 5.7
  • MacOS 10.15.5

前提条件

  • Dockerhubのアカウントを作成している。
  • Docker for Macをインストールしている。
  • Dockerの基礎はある程度抑えている。

Dockerの基本的なことはこちらの記事が参考になります。
いまさらだけどDockerに入門したので分かりやすくまとめてみた

対象読者

今回は開発環境を構築することを目標とする為、Dockerに関する基礎的な部分はある程度抑えている方とします。

Railsの開発環境構築

DockerでRailsの開発環境を構築するには以下のファイルが必要になります。

  • Dockerfile
  • Gemfile
  • Gemfile.lock
  • docker-compose.yml

1.作成するアプリ名のディレクトリを作成する。

まずは、上記のファイルを作成するディレクトリを作成します。

#ターミナル
$ mkdir my-app

2.作成したディレクトリに移動する。

$ cd my-app

3.Dockerfileを作成する。

1.で作成したディレクトリ内にDockerfileを作成します。

$ touch Dockerfile

Dockerfileとは?

Dockerでは、dockerhubで公開されているimageを元にコンテナを起動することができるが、必要なパッケージや各種の設定を含んだDocker imageを自分で作成して使用したい場合が出てくる。その場合にDockerfileを用意して、それを元にDocker imageを作成することができる。
Dockerfileにはベースのimageに対して実行する内容を記述する。

4.Dockerfileに記述する。

Dockerfile
# ベースイメージ 今回はrubyのimage。
FROM ruby:2.6.3

# 必要なパッケージのインストール
RUN apt-get update -qq && \
    apt-get install -y build-essential \ 
                       libpq-dev \        
                       nodejs           

# 作業ディレクトリの作成、設定
RUN mkdir /my-app

#作業ディレクトリを指定している
WORKDIR /my-app

# ホスト側(ローカル)のGemfileを追加する(ローカルのGemfileは別途事前に作成しておく)
COPY ./Gemfile /my-app/Gemfile
COPY ./Gemfile.lock /my-app/Gemfile.lock

# Gemfileのbundle install
RUN bundle install
COPY . /my-app

5.Gemfileを作成する。

$ touch Gemfile

6.Gemfileに記述する。

Gemfile
source 'https://rubygems.org'
gem 'rails', '5.2.3'

7.空のGemfile.lockを作成する。

$ touch Gemfile.lock

8.docker-compose.ymlを作成する。

$ touch docker-compose.yml

Docker Composeとは?

Dockerでは1つのコンテナには、1つのアプリケーションのみを入れておき、複数のコンテナを組み合わせてサービスを構築するという方法が推奨されている。
Docker Composeは、複数のコンテナで構成されるアプリケーションについて、Docker imageのbuildや各コンテナの起動・停止などをより簡単に行えるようにするツール。

docker-compose.ymlとは?

Docker Composeを使用する際に必要となるファイルのこと。

docker-compose.ymlには以下の内容を定義します。

  • Docker imageをbuildするための情報(使用するDockerfile、image名など)
  • コンテナ起動するための情報(ホストとの共有ディレクトリ設定やポートフォワードなどの起動オプションなど)
  • 使用するDockerネットワーク など

9.docker-compose.ymlに記述する。

docker-compose.yml
version: '3' # Dockerのバージョンを指定
services:
  db: # データベースサーバ用のコンテナの設定を記述
    image: mysql:5.7 # コンテナで使用するイメージ名を記述
    environment:
      MYSQL_ROOT_PASSWORD: password # 任意のパスワードを設定
      MYSQL_DATABASE: root # 任意のデータベース名を設定
    ports:
      - "3306:3306" # ホストの3306ポートとコンテナの3306ポートを接続する。
    volumes:
      - ./db/mysql/volumes:/var/lib/mysql #ホストの./db/mysql/volumesをコンテナ内の/var/lib/mysqlにマウントする。Dockerのコンテナと、ローカルを同期している。コンテナを削除してもデータは永続化する。

  web: # アプリケーションサーバ用のコンテナの設定を記述
    build: . # docker-compose.ymlと同じ階層にあるDockerfileを使ってimageをbuildするための記述
    command: bundle exec rails s -p 3000 -b '0.0.0.0' # コンテナ立ち上げ時に起動するコマンド。railsを実行する。

    volumes:
      - .:/my-app # 作業ディレクトリをコンテナ内の/my-appにマウントする。
    ports:
      - "3000:3000" # ホストの3000ポートとコンテナの3000ポートを接続する。
    depends_on:
      - db # 依存関係を表している。dbが起動してからwebが起動するという意味。

10.コンテナを起動し、コンテナ内でrails newを実行する。

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

runコマンドは、imageの構築から、コンテナの構築・起動まで行います。
また、runコマンドを介して引数で指定したサービスのコンテナ内でコマンドを実行できます。つまり、ここでは生成されたコンテナ内でrails newを行っています。
--forceオプションはファイルが存在する場合に上書きで作成するためのオプション。
--database=mysqlオプションは使用するデータベースの指定をするためのオプション。
--skip-bundleオプションはbundle installをスキップするためのオプション。

11.database.ymlを修正する。

rails newで作成されたデータベースの接続設定ファイルにはホスト名とパスワードが設定されていません。railsアプリケーションがデータベースに接続できるようにするため、database.ymlを修正します。

database.yml

default: &default
  adapter: mysql2
  encoding: utf8
  pool: <%= ENV.fetch("RAILS_MAX_THREADS") { 5 } %>
  username: root
  password: password # docker-compose.ymlのMYSQL_ROOT_PASSWORD
  host: db # docker-compose.ymlのservice名

12.buildを実行する。

$ docker-compose build

ここでbuildを実行する理由は10.で実行したコマンドによりGemfileの内容が書き換わっている為です。

13.Dockerを起動する。

$ docker-compose up -d # docker-compose.ymlを参照してコンテナが一斉起動する。

注意点としてここで実行するdocker-composeコマンドはdocker-compose.ymlを元に実行が進むので、docker-compose.ymlがあるディレクトリ上で実行する必要があります。

14.データベースを作成する。

docker-compose run webをコマンドの先頭につけることでコンテナ内でコマンドを実行できるので、

$ docker-compose run web rails db:create

を実行すれば、データベースが作成できます。

要は、docker-compose run webに続けていつものローカルで開発している時のコマンドが使えます。

では、localhost:3000に接続してみましょう。

以下の画面が表示されれば完了です。

gemを入れてbundle installしてみる。

開発環境が整ったので試しにgemを入れてbundle installしてみます。

Gemfile
gem 'devise'
$ docker-compose run web bundle install

そして、

$ docker-compose run web rails g devise:install

しかし以下のようなエラーが出ました。

Could not find bcrypt-3.1.15 in any of the sources
Run `bundle install` to install missing gems.

bundle installしたはずなのに。。。
これは12.のところと同じ現象です。つまり、ローカルで書き換えたGemfileがコンテナ内のGemfileに反映されていない。ここでは再度、docker-compose buildを行う必要があります。理由はDockerfileを見れば分かります。

Dockerfile

COPY ./Gemfile /my-app/Gemfile
COPY ./Gemfile.lock /my-app/Gemfile.lock

Dockerfile内でimageをbuildする際にローカル側のGemfileをコンテナ側にコピーしていました。ですから、現状ローカルのGemfileの変更はコンテナのGemfileには反映されていない訳です。これを反映させる為に、再度docker-compose buildを行う(imageをbuildし直す)必要があるという訳です。
では、再度docker-compose buildを実行します。

$ docker-compose build

もう一度、エラーが出たコマンドを試します。

$ docker-compose run web rails g devise:install

今度は上手く行きました。

しかし、gemを入れるたびに毎回docker-compose buildするのは面倒臭い。。。

という訳で、毎回docker-compose buildをしなくてもいいようにこちらの記事を参考にさせてもらい、docker-compose.ymlを編集します。
docker-composeでRailsのGemを更新する時、docker buildするのを回避したい

docker-compose.yml
version: '3'
services:
  db:
    image: mysql:5.7
    environment:
      MYSQL_ROOT_PASSWORD: password
      MYSQL_DATABASE: root
    ports:
      - "3306:3306"
    volumes:
      - ./db/mysql/volumes:/var/lib/mysql

  web:
    build: . 
    command: bundle exec rails s -p 3000 -b '0.0.0.0'
    volumes:
      - .:/my-app
      - gem_data:/usr/local/bundle # ローカルのgem_dataをコンテナ内の/usr/local/bundleにマウントする。
    ports:
      - "3000:3000"
    depends_on:
      - db

volumes: # 上記のvolumesのgem_dataはローカルのものを使うことを指定している。
  gem_data:

これで、gemをインストールするたびにdocker-compose buildをしなくてもよくなりました。

binding.pryをしたい時

docker-compose.ymlに以下を記述します。

docker-compose.yml
web:
  tty: true
  stdin_open: true

SequelProでデータベースを可視化する。

私はローカルで開発を行う際、SequelProを使用してデータベースを可視化していましたが、コンテナの仮想環境下では現状SequelProでデータベースを可視化することはできません。
docker-compose.ymlを以下の様に書き換えSequelProでデータベースを可視化できるよう設定していきます。

docker-compose.yml
services:
  db:
    image: mysql:5.7
    environment:
      MYSQL_ROOT_PASSWORD: password
      MYSQL_DATABASE: root
    ports:
      - "4306:3306" # ホストの4306ポートをコンテナ内の3306ポートに接続するよう書き換える。
    volumes:
      - ./db/mysql/volumes:/var/lib/mysql

次に、sequelpro起動時のモーダル内のタブを標準タブに切り替え、下記の通りに入力します。

名前: defaultのまま
ホスト: 127.0.0.1    # 自分自身を表すIPアドレス
ユーザー名: root    # database.ymlに記載のユーザー名
パスワード: password  # database.ymlに記載のパスワード
データベース: 空欄のまま
ポート: 4306      # docker-compose.ymlに記載したlocal側のports番号

これでdocker環境下でもデータベースが可視化できるようになります。

参考記事・参考動画

今回Dockerを学習するにあたり、多くの方の記事を参考にさせて頂きました。
ありがとうございました。
docker-compose コマンドまとめ
docker-compose up とか build とか start とかの違いを理解できていなかったのでまとめてみた。
既存のRailsアプリをDockerコンテナで動かす方法+sequel proによるDBコンテナ可視化
Dockerを使用したRails開発①(環境構築)
【rails環境構築】docker + rails + mysql で環境構築(初心者でも30分で完了!)

12
6
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
12
6