既存のRailsアプリにDockerを導入

内容

すでにRailsアプリを作成している段階でDockerも導入したいと考えたので、アプリ作成後からDockerを導入する方法についてまとめる

バージョン

基礎知識

  • Dockerfileとは
    →Docker imageの設計図で、DockerfileからDocker imageを作る
    →INSTRUCTION argumentsの形で書いていく
  • FROM(instruction)
    →ベースとなるイメージを決定
    →DockerfileはFROMから書き始める
  • RUN(instruction)
    Linuxコマンドを実行
    →RUNを使うことで好きなようにカスタマイズ
    →RUN毎にImage Layerが作られる(RUNをずらっと書いていくとLayerの数が膨大になりimageが大きくなってしまう)
  • imageのLayer数を最小限にするには?
    →Layerを作るのはRUN、COPY、ADDの3つ
    →コマンドを&&で繋げる
    →バックスラッシュ(\)で改行する
  • $apt-get
    →$apt-get update:新しいパッケージリストを取得、$apt-get install をインストール
  • CMD(instruction)
    →コンテナのデフォルトのコマンドを記述
    →CMD["executable", "params1", "params2"]
    →原則Dockerfileの最後に記述
    →RUNはLayerを作る、CMDは作らない
  • COPYとADD(instruction)
    →単純にファイルやフォルダをコピーする場合はCOPYを使う
    →tarの圧縮ファイルをコピーして解凍したい時はADDを使う(大きいファイルの時)
  • CMDとENTRYPOINT(instruction)
    →ENTRYPOINTでもデフォルトのコマンドを指定することができるが、run時に上書きできない
    →ENTRYPOINTがある場合は、CMDは["params1", "params2"]の形を取る
    →コンテナをコマンドのように使いたい時に使う
  • ENV(instruction)
    環境変数を設定する
  • WORKDIR(instruction)
    →Docker instructionの実行ディレクトリを変更する
  • docker compose
    →複数のコンテナを簡単にrunできるDockerのツール
    →docker runコマンドが長くなる時や、複数のコンテナをまとめて起動する時に使う

手順1 DockerHubの登録とDockerのインストール

  • DockerHubのHPでサインアップ
  • 無料の枠を選択
  • メールが送られてくるのでログイン
  • 「Download the desktop application」でDocker Desktopをダウンロード
  • Docker.dmgがダウンロードできたらダブルクリックし、インストール→アプリケーションフォルダに移動

手順2 Dockerfileを作成

既存アプリケーションのルートディレクトリにDockerfileを作成し、下記のように記述
※今回はアプリのディレクトリ名をsample_appとする
Dockerfile

FROM ruby:2.6.5
RUN curl -sS https://dl.yarnpkg.com/debian/pubkey.gpg | apt-key add - \
    && echo "deb https://dl.yarnpkg.com/debian/ stable main" | tee /etc/apt/sources.list.d/yarn.list
RUN apt-get update -qq && apt-get install -y \
    build-essential \
    libpq-dev \
    nodejs \
    yarn
WORKDIR /sample_app
COPY Gemfile ./Gemfile
COPY Gemfile.lock ./Gemfile.lock
RUN gem install bundler
RUN bundle install
COPY . /sample_app
COPY entrypoint.sh /usr/bin/
RUN chmod +x /usr/bin/entrypoint.sh
ENTRYPOINT ["entrypoint.sh"]
EXPOSE 3000
CMD ["rails", "server", "-b", "0.0.0.0"]

手順3 docker-compose.ymlを作成

手順2同様にルートディレクトリにdocker-compose.ymlを作成し、下記のように記述
docker-compose.yml

version: '3' #docker-composeのバージョン
services:
  web:
    build: .
    command: bash -c "rm -f tmp/pids/server.pid && bundle exec rails s -p 3000 -b '0.0.0.0'"
    volumes:
      - .:/sample_app
    ports:
      - 3000:3000
    depends_on:
      - db
    tty: true
    stdin_open: true
  db:
    image: mysql:5.6.51 #既存アプリとあわせる。ターミナルに[$ mysql --version]で確認
    environment:
      MYSQL_ROOT_PASSWORD: ${MYSQL_ROOT_PASSWORD} #あなたのパスワード
      MYSQL_DATABASE: root
    ports:
      - "4306:3306"
    volumes:
      - ./mysql-confd:/etc/mysql/conf.d
volumes:
  mysql-data:

手順4 config/database.ymlの編集

configディレクトリにあるdatabase.ymlを下記のように編集
config/database.yml

default: &default
  adapter: mysql2
  encoding: utf8mb4
  pool: <%= ENV.fetch("RAILS_MAX_THREADS") { 5 } %>
  username: root
  password: <%= ENV.fetch("DATABASE_PASSWORD") %> #あなたのパスワード
  socket: /tmp/mysql.sock
  host: db

development:
  <<: *default
  database: sample_app_development

test:
  <<: *default
  database: sample_app_test

手順5 .envファイルに環境変数を設定し、.gitignoreに.envを追加

手順6 entrypoint.shを作成

手順2、3同様にルートディレクトリにentrypoint.shを作成し、下記のように記述
entrypoint.sh

#!/bin/bash
set -e

# Remove a potentially pre-existing server.pid for Rails.
rm -f /sample_app/tmp/pids/server.pid

# Then exec the container's main process (what's set as CMD in the Dockerfile).
exec "$@"

手順7 Dockerイメージの作成

ターミナルで下記のコマンドを実行し、Dockerイメージを作成
ターミナル

sample_app% docker-compose build

手順8 Dockerコンテナを起動

ターミナルで下記のコマンドを実行し、Dockerコンテナを起動 ターミナル

sample_app% docker-compose up -d

手順9 コンテナ内にデータベースを作成する

ターミナルで下記のコマンドを実行し、コンテナ内にデータベースを作成 ターミナル

sample_app% docker-compose run web rails db:create

手順10 作成したデータベースのマイグレーションを実行

ターミナルで下記のコマンドを実行し、データベースのマイグレーションを実行 ターミナル

sample_app% docker-compose run web rails db:migrate

手順11 Gemのインストール(これいらないかも)

ターミナルで下記のコマンドを実行し、Gemをインストール ターミナル

sample_app% docker-compose exec web bundle install

以上で導入完了
localhost:3000に接続するとアプリケーションが表示される(rails sはいらない)

エラー1

手順9のコマンド実行時、以下のエラーが出現
ターミナル

Creating sample_app_web_run ... done
warning Integrity check: System parameters don't match                                                    
error Integrity check failed                                                                              
error Found 1 errors.                                                                                     


========================================
  Your Yarn packages are out of date!
  Please run `yarn install --check-files` to update.
========================================


To disable this check, please change `check_yarn_integrity`
to `false` in your webpacker config file (config/webpacker.yml).


yarn check v1.22.5
info Visit https://yarnpkg.com/en/docs/cli/check for documentation about this command.


ERROR: 1

yarnのパッケージの中に古いものが存在していることが原因のようなので、以下のコマンドを実行してyarnをアップグレードしてみた
ターミナル

% yarn upgrade

しかし同じようなエラーが出たので、再度エラーを確認
ターミナル

To disable this check, please change `check_yarn_integrity`
to `false` in your webpacker config file (config/webpacker.yml).

上記のようなエラーが出ていたため、「config/webpacker.yml」ファイルのcheck_yarn_integrity箇所をfalseに変更すれば良いと解釈して、実際に変更してみる
config/webpacker.yml

# Verifies that correct packages and versions are installed by inspecting package.json, yarn.lock, and node_modules
check_yarn_integrity: false

上記で解決した