LoginSignup
30
22

More than 3 years have passed since last update.

②Dockerを初めて導入してRails sする (2020.4時点)

Last updated at Posted at 2020-04-13

1.これからDocker導入します、という方は、まず、こちらを見ていただけると幸いです。

①Dockerを初めて導入して基本操作する (2020.4時点)

本稿は、
Dokerコンテナイメージを作成して、
コマンド「docker-compose up 」でRails s起動する
という流れです。

自分と同じように、
何していいかわからないゼロスタートの方になるべくわかるようにしたいと思っています。

2.前提

Docker for Macアプリをインストールしている
Dockerサービスが起動している
DockerHubでサインインしている
VSCodeで編集
ターミナル使用
Sequelpro使用

<環境>
macOS : Catalina 10.15.3
Docker version : 19.03.8
ruby : 2.5.1
Rails : 5.2.4.1
MYSQL :5.6

<参考>
Dockerはこう書くとこう動くよ、というのがわかりやすい、こちらの動画ををおすすめします!
Docker超入門 Part01〜Part04
https://youtu.be/7mwoTs0LoYA

今から追いつくDocker講座!AWS ECSとFargateで目指せコンテナマスター!〜シリーズ1回目〜
https://youtu.be/DS5HBTMG1RI

では、はじめていきましょう!

3.Dockerfile を新規作成して編集する

今回はVSCodeを使って進めます。
ローカルで作業中のRailsアプリを開き、Dockerfileをアプリのディレクトリの一番上位に新規作成します。

新規作成するファイル名は「 Dockerfile 」 です。
image.png

Dockerfileに、ベースとするDockerイメージ(Ruby)に対して実行する内容を記述します。

このように記述してみます。

Dockerfile

        #FROM(フロム)はDocker に対して ベースとなるRubyイメージを指定する
FROM ruby:2.5.1
        #run(ラン)はdocker-compose buildコマンドで実行される
        #Railsの起動に必要となるnodejsをインストールする
        #apt-getコマンドはUbuntuパッケージ管理システム=APTライブラリを利用してパッケージ操作・管理するコマンド
        #①updateで常に新しいパッケージinstall →②-qqはエラー以外は表示しない →③常にyesの-y指定
        #→④ubuntuのbuild-essential(OS基礎開発パッケージ) → ⑤libpq-dev(OS開発パッケージ)
        #→⑥nodejs(サーバーサイドのJavaScript)  の順番でインストールする
        # \ バックスラッシュでコードを改行して見易くする       (\ はoption+¥です)
RUN apt-get update -qq && \
        apt-get install -y build-essential \
                                libpq-dev \
                                nodejs
        #今回はapp_nameという名前のディレクトリ(場所)を作ります
        #mkdir(メイクディレ)=(make directory)
        #ディレクトリ名は自由です
RUN mkdir /app_name
        /#WORKDIR(ワークディレ)は、RUNやADDなどの命令実行するカレントディレクトリ
        #カレントディレクトリ(作業位置)をapp_nameに移動(cdコマンドと同じ)
WORKDIR /app_name
        /#COPY(コピー)はローカル側のファイルをdockerイメージ側の指定したディレクトリにコピーする
        #ローカルのGemfileをapp_name/Gemfileにコピーする
        #ローカルのGemfile.lock をapp_name/Gemfile.lockにコピーする
        #docker-compose build 実行する前に、ローカルのGemfile.lock内を全削除しておきます(エラー対策)
COPY Gemfile /app_name/Gemfile
COPY Gemfile.lock /app_name/Gemfile.lock
        #gem install bundler インストールを実行する
        #bundle install を実行する
RUN gem install bundler
RUN bundle install
        #ADD(アド)はローカル側のファイルをdockerイメージ側の指定したディレクトリに追加(コピー)する
        #ローカルの(.)カレントディレクトリをコンテナのapp_nameディレクトリに追加(コピー+解凍)する
ADD . /app_name

このような感じです。(コメントアウトなし)
image.png

コメントアウトあり
image.png

プラスウイングTVさんの「Docker超入門 Part01 - Dockerを使った開発環境構築」がとてもわかりやすかったので引用させていただきます。(ありがとうございます!)
https://youtu.be/7mwoTs0LoYA

・Rails の環境構築の元になるRuby、Rails、Nodejs、MySQLは、DockerHub上にあって勝手にそこから引っ張ってきてくれる。
・DockerHubでrubyを検索 すると、真ん中あたりにruby2.5ありました。
 これをFROMに書けば勝手にベースにしてくれるのですね、すごい楽ちん!
image.png
image.png

Dockerfile作成 Qiitaで参考になった記事

Dockerfileを書くためのベストプラクティス【参考訳】v18.09https://qiita.com/zembutsu/items/a96b68277d699f79418d
Docker × Ruby on Rails × MySQLの環境構築https://qiita.com/tatsuo-iriyama/items/0bf3b08de03280314c91
Ruby on Rails 「途中まで作ったアプリにDockerを導入したい」に挑戦してみるhttps://qiita.com/majorboy/items/9fbfc78fc7bbc1f35e77#comment-60a244ed29cedf06555d
Docker × Ruby on Rails × MySQLの環境構築https://qiita.com/tatsuo-iriyama/items/0bf3b08de03280314c91
Docker で環境変数をホスト OS 側からゲスト OS (コンテナ)に渡す方法(各種)https://qiita.com/KEINOS/items/518610bc2fdf5999acf2
Docker入門 ~Dockerfile編~ https://qiita.com/takaday/items/08c8269dc926af8cb661
Dockerfile のコマンド一覧https://qiita.com/FumiyaShibusawa/items/a0be39d28139a044157d
Bundlerの使い方 https://qiita.com/oshou/items/6283c2315dc7dd244aef
[Ubuntu] apt-get まとめhttps://qiita.com/white_aspara25/items/723ae4ebf0bfefe2115c

Dockerfile作成 ググって参考になった記事

公式チュートリアル https://docs.docker.com/compose/rails/#connect-the-database
Dockerfile のベストプラクティス http://docs.docker.jp/engine/articles/dockerfile_best-practice.html
Dockerfile リファレンス http://docs.docker.jp/engine/reference/builder.html
Linuxのコマンド(とか)の呼び方をこじらせるhttps://unskilled.site/独学でプログラミングを勉強するとlinuxのコマンド/
build-essentialとは https://qiita.com/h_tyokinuhata/items/431a56fb054145468c16
Ubuntuとは?https://eng-entrance.com/what-is-ubuntu
パッケージ: build-essential (12.4ubuntu1) https://packages.ubuntu.com/ja/bionic/build-essential
パッケージ: libpq-dev https://packages.ubuntu.com/ja/bionic/libpq-dev
mkdirコマンドの詳しいまとめhttps://eng-entrance.com/linux-command-mkdir
なぜ、Ruby on Railsの動作にNode.jsが必要なのか https://www.xenos.jp/~zen/blog2/index.php/2019/03/19/post-1831/

4.docker-compose.ymlを編集する

・DockerComposeは、複数コンテナを定義して同時起動するオーケストレーションツールです。

・docker-compose.ymlは設定記述用途のYAMLファイル形式でCompose ファイルと呼ばれ、
 サービス(services) 、 ネットワーク(networks) 、 ボリューム(volumes) を定義し、
アプリケーション全ての依存関係(データベース、キュー、キャッシュ、ウェブ・サービス、API 等)を設定します。

docker-compose.ymlをRailsアプリのディレクトリの一番上位に新規作成します。
image.png

このように記述してみます。

docker-compose.yml

        #docker-composeのバージョン(2020.4.12時点では"3"で問題なさそう)
version: '3'
        #servicesは各コンテナを定義します
services:
        #dbは1つのコンテナ名です(1コンテナ1プロセス)
        #ローカルmysql version確認 → mysql  Ver 14.14 Distrib 5.6.47
        #DockerHubでmysql5.6を確認できたので5.6と記述
  db:
    image: mysql:5.6
        #environmentは環境変数を追加します
        #環境変数MYSQL_ROOT_PASSWORDに、今回はpasswordと入れます(パスは自由)
        #パスワードの直打ちは危険なので、環境変数を使って秘匿します
    environment:
      MYSQL_ROOT_PASSWORD: 'password'
        #portsは公開用のポートで、ホスト側とコンテナ側の両方のポートを指定します( ホスト側:コンテナ側 )
        #ローカルMYSQLはポート確認すると3306を使用中なので、ホスト側は4306にします(4にした深い意味はありません)
        #ローカル側MYSQLは大抵は自動で3306になっているそうです
        #Sequelproにて4036(例として)を指定すると、DockerのMYSQLがSequelproで見れるようになります。
    ports:
      - "4306:3306"
      #webは1つのコンテナ名です(1コンテナ1プロセス)
      #buildはdockercompose.ymlを基点に指定フォルダー配下のDockerfileを元にコンテナを作成します。
      #指定は .  ルート (つまり、ルート直下に置いた先ほど作成したDockerfileを参照する、という記述です)
  web:
    build: .
      #commandは任意にコマンドを上書きできます。
      #bashはOSカーネルとユーザの橋渡しするプログラムシェルです
      #起動停止の繰り返しで起こるエラー「A server is already running.」の原因、pidをbuildのたび削除する(unicorn master KILLと同じですね)
      #Rails serverを立ち上げた際にURL(http://0.0.0.0:3000)にアクセス=localhost:3000
    command: bash -c "rm -f tmp/pids/server.pid && bundle exec rails s -p 3000 -b '0.0.0.0'"
      #volumesではパスを指定するとDockerエンジンはボリュームを作成します
      #カレントディレクトリ(.)をapp_nameディレクトリにマウントします。
    volumes:
      - .:/app_name
      #portsは公開用のポートのことでホスト側とコンテナ側の両方のポートを指定します( ホスト側:コンテナ側 )
      #localhost:3000にアクセスするとコンテナの3000ポートにつながります
    ports:
      - "3000:3000"
      #depends_onはサービス間の依存関係を指定します
      #webコンテナ側からdbコンテナにdbの名前で接続できるようになります
      #docker-compose up を実行したら、web:コンテナのプロセスを開始するより前にdb:コンテナのプロセスを先に実行します
    depends_on:
      - db

image.png

DockerHubでMYSQLを調べる

DockerHubで検索すると、MYSQLイメージが見つかります。
image.png

ローカルでMYSQLのバージョンとポートを調べる

ターミナル
mysql -u root

でローカルのMYSQLに入ります。

ターミナル
mysql> これがでたら

mysql> show variables like 'port';  を実行します

すると、バージョンとポートの情報が見れます。
image.png
私のRailsアプリ(ローカル)のMYSQLは、version:5.6.46、ポートは3306番でした。

docker-compose.yml作成 Qiitaで参考になった記事

Docker ドキュメント日本語化プロジェクトhttp://docs.docker.jp/compose/toc.html#
YAMLとは何か? - いつもRailsの設定ファイルで出てくるやつの正体https://qiita.com/Yama-to/items/587544993fb62610528a
MySQLのバージョン確認方法https://qiita.com/haxpig/items/b270acb9550efddd5fe5
今さら聞けない!OSとは何か?https://www.sejuku.net/blog/6084
bash 入門https://rat.cis.k.hosei.ac.jp/article/linux/bash_intro.html
【初心者向け】Linuxカーネルって一体なんだ?https://qiita.com/uguis410/items/17ec1e447e9716bfdca7
docker-compose upしたときに「A server is already running.」って言われないようにするhttps://qiita.com/paranishian/items/862ce4de104992df48e1
Bundle installからRails serverを起動するまでhttps://wonderful-tereshkova-38f91d.netlify.com/Bundle%20installからRails%20serverを起動するまで/
rails sとは localhostとはhttps://qiita.com/MIRAI1221/items/29f764db4f50bb44e3f4
MacでMySQL使用準備あれこれhttps://qiita.com/E-11/items/a230f6564614eeddef8c
docker-compose up したコンテナを起動させ続ける方法https://qiita.com/sekitaka_1214/items/2af73d5dc56c6af8a167

5.database.yml を編集する

Railsアプリには config/database.yml が既に存在しています。
このファイルを編集します。

・MYSQLにパスワードを設定します。
  password: password (←これ) #docker-compose.ymlのMYSQL_ROOT_PASSWORD
・データベースが動作しているホスト名を設定します。
  host: db (←これ )#docker-compose.ymlのservice名の db

docker-compose.ymlはこんな感じです。
image.png

このように記述します。

config/database.yml
default: &default
  adapter: mysql2
  encoding: utf8
  pool: <%= ENV.fetch("RAILS_MAX_THREADS") { 5 } %>
  nickname: root
  password: password  #(←ここ、passwordを追記します)
  socket: /tmp/mysql.sock
  host: db             #(←ここ、host:dbを追記します)

こんな感じになります。
image.png

これで準備は完了しました!....のはずでした。

エラー発生です!

無事にDockerコンテナイメージを構築できるか、祈りながらコマンド実行!

ターミナル
docker-compose build

はい、Dockerさん、なんか怒ってます。

エラー文
You must use Bundler 2 or greater with this lockfile.
(このロックファイルでは、Bundler 2以上を使用する必要があります。)
ERROR: Service web failed to build: The command /bin/sh -c bundle install returned a non-zero code: 20

振り返ると、コンテナくじらさんはこう言ってたようです。
Dockerfile36行でバンドラーのバージョン指定がなかったから、最新の2系をインストールしたよ!
Dockerfile37行でバンドルインストールしろって言うから実行したけど無理でしたよ。

バンドラー問題を解決した方法

お世話になった記事です(ありがとうございました!)

Railsの既存AppをDockerに切り替える際に役立つ記事
https://qiita.com/mylevel/items/ff86875df64e3d002fc9

・エラー解決でやったこと
 1. Dockerfileに RUN gem install bundler -v 1.3.0 と1系のバージョン指定した
image.png

 2. ローカルのGemfile.lockを command+A+✖️で全削除した
image.png

 3. docker-compose build コマンドを実行

ターミナル
docker-compose build

これでエラーを解決できました。

6.build コマンドで imageを構築する

buildコマンドを実行します。
buildコマンドは指定したDockerfileを読み込み、1行1行命令を実行しながらイメージを構築します。

ターミナル
docker-compose build

ターミナルはこんな感じです。
image.png
無事、最後のSTEPまで成功しました。
image.png

7.DockerコンテナのMYSQLにDB(db:create)を作成し、テーブル作成(db:migration)する

DockerコンテナのMYSQLにRailsアプリのDB作を作成します。

ターミナル
docker-compose run web bundle exec rake db:create

エラー発生です!

また怒られました。今度は、くじらデーモン閣下。

ターミナル
user@keisukeagamiAir nomadcafe % docker-compose run web bundle exec rake db:create
Starting nomadcafe_db_1 ... done
Error response from daemon: Mounts denied: 
The path /Applications/nomadcafe
is not shared from OS X and is not known to Docker.
You can configure shared paths from Docker -> Preferences... -> File Sharing.
See https://docs.docker.com/docker-for-mac/osxfs/#namespaces for more info.

google様の通訳:
デーモンからのエラー応答:マウントが拒否されました:
パス/ Applications / nomadcafe
OS Xからは共有されず、Dockerには認識されません。
Docker-> Preferences ...-> File Sharingから共有パスを設定できます。
詳細については、https//docs.docker.com/docker-for-mac/osxfs/#namespacesを参照してください。

デーモンからマウントを拒否される問題を解決した方法

お世話になった記事です(ありがとうございました!)

Docker for Macでコンテナとのボリュームマウントに苦労した話
https://qiita.com/harukisan/items/31f15780760ab2f3d213

・エラー解決でやったこと
1.Docker for macアプリ > Resources > FILESHARINDに移動
2.一番下の+ボタンを押して、ローカルのRailsアプリファイルを指定
3.Apply&Restartをおしてリロードを完了

Docker for macを開きます。
(デスクトップ上端メニューバーのwifiやbluetoothあたりにある、くじらアイコンを触ってpreferences...を選択します)
image.png
作業しているRailsアプリのファイルを選択します。
image.png
選択したらリロードします。
image.png
Apply&Restartボタンを押して、リロードしました。

あらためて、DockerコンテナのMYSQLにRailsアプリのDB作を作成します。

ターミナル
docker-compose run web bundle exec rake db:create

image.png
できました!

続いて、マイグレーションしてテーブルを作ります。

Dockerコンテナはlocalとは環境が異なりますので、DB作成とマイグレーションが必要です。


Dockerコンテナでのrailsコマンドは通常のコマンドの前に
「docker-compose run web」をつけて実行します。

ターミナル
docker-compose run web bundle exec rake db:migrate

image.png
無事、マイグレーションできました。

8.コンテナを起動する docker-compose up (or start)

image構築、コンテナ構築、コンテナ起動をやってくれるコマンドを実行してみます。

ターミナル
docker-compose up

すると、ターミナルはこんな感じです。
image.png
image.png
最後に、Rails sのときと同じ見覚えのある単語が出てきました!

localhost:300にアクセスします。
image.png

無事、アプリが起動しました!

9.最後に

当方、
実務未経験+初学者+テッ○キャンプ卒業+転職活動中であります。
まだまだ、素人同然なので、間違いがございましたらご教示いただけるとありがたいです。

たくさんのQiita記事でコードを見合わせたり、エラー解決記事が投稿されてたり、そのおかげでここまで実装できました。
記事を投稿してくださった先輩方に感謝しております。

この先も本番環境でのdocker実装に向けて進みつつ、わかりやすい記事を寄稿していきたいと考えています

ローカル・Dockerで開発環境を整えるまでの続編

②Dockerを初めて導入してRails sする (2020.4時点)
③Docker MYSQLにデモデータ(seed_fu)を投入する!(2020.4時点)
④ローカルDocker環境でデータ永続化、entrypointでseed_fuをやり直しする(2020.4.時点)
⑤AWS仮想サーバを利用する、AWSアカウント作成 + EC2インスタンス作成(2020.4時点)
こちらも続けて見ていただけると流れがわかると思います。

30
22
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
30
22