こたつとみかんとプログラミング

33才実務未経験ですがウェブエンジニアにジョブチェンジするために勉強したことをアップするためのブログです。

Docker 環境に Entrykit と ChromeDriver を導入する

課題の Docker 環境に導入されていた Entykit と、system spec を利用するための ChromeDriver を自分の環境にも導入したのでメモ。

FROM ruby:2.6.5

ENV ENTRYKIT_VERSION 0.4.0

# Entrykitのインストール
RUN wget https://github.com/progrium/entrykit/releases/download/v${ENTRYKIT_VERSION}/entrykit_${ENTRYKIT_VERSION}_Linux_x86_64.tgz \
  && tar -xvzf entrykit_${ENTRYKIT_VERSION}_Linux_x86_64.tgz \
  && rm entrykit_${ENTRYKIT_VERSION}_Linux_x86_64.tgz \
  && mv entrykit /bin/entrykit \
  && chmod +x /bin/entrykit \
  && entrykit --symlink

# yarnのインストール
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

# chromedriverのインストール
RUN CHROMEDRIVER_VERSION=`curl -sS chromedriver.storage.googleapis.com/LATEST_RELEASE` \
  && wget -N http://chromedriver.storage.googleapis.com/$CHROMEDRIVER_VERSION/chromedriver_linux64.zip -P ~/ \
  && unzip ~/chromedriver_linux64.zip -d ~/ \
  && rm ~/chromedriver_linux64.zip \
  && chown root:root ~/chromedriver \
  && chmod 755 ~/chromedriver \
  && mv ~/chromedriver /usr/bin/chromedriver \
  && sh -c 'wget -q -O - https://dl-ssl.google.com/linux/linux_signing_key.pub | apt-key add -' \
  && sh -c 'echo "deb [arch=amd64] http://dl.google.com/linux/chrome/deb/ stable main" >> /etc/apt/sources.list.d/google-chrome.list'

RUN apt-get update -qq && apt-get install -y \
  build-essential \
  google-chrome-stable \
  libpq-dev \
  nodejs \
  yarn \
  && apt-get clean \
  && rm -rf /var/lib/apt/lists/*

# 作業ディレクトリの作成、設定
RUN mkdir /ketsuatsu_app
WORKDIR /ketsuatsu_app

# ローカルのGemfileを追加
COPY Gemfile /ketsuatsu_app/Gemfile
COPY Gemfile.lock /ketsuatsu_app/Gemfile.lock
ENV BUNDLER_VERSION 2.1.2
RUN gem install bundler -v $BUNDLER_VERSION
RUN bundle install --no-deployment
COPY . /ketsuatsu_app

ENTRYPOINT [ \
  "prehook", "bundle install -j3 --path vendor/bundle", "--", \
  "prehook", "ruby -v", "--", \
  "prehook", "node -v", "--" \
]

Entykit で追加したもの

Entrykit のファイルを展開して実行。

RUN wget https://github.com/progrium/entrykit/releases/download/v${ENTRYKIT_VERSION}/entrykit_${ENTRYKIT_VERSION}_Linux_x86_64.tgz \
  && tar -xvzf entrykit_${ENTRYKIT_VERSION}_Linux_x86_64.tgz \
  && rm entrykit_${ENTRYKIT_VERSION}_Linux_x86_64.tgz \
  && mv entrykit /bin/entrykit \
  && chmod +x /bin/entrykit \
  && entrykit --symlink

ここら辺はテンプレ通り。ファイルをダウンロードし、展開し、Entrykit のコマンドを実行できるようにしている。

ENTRYPOINT の記述

ENTRYPOINT [ \
  "prehook", "bundle install -j3 --path vendor/bundle", "--", \
  "prehook", "ruby -v", "--", \
  "prehook", "node -v", "--" \
]

ENTRYPOINT は、コンテナ起動時に実行される命令を指定する場所。
今回は bundle install と、ruby, node.js のバージョン確認を指示している。
bundle install がないと、もし Docker をビルドした後に新しく gem を追加した場合、次のコンテナ起動時に gem がないと怒られてしまうとのこと。
buildが時間かかりすぎなせいで、検証できていないが、そういうことらしい。

ChromeDriver で追加したもの

ChromeDriver 自体のインストール

RUN CHROMEDRIVER_VERSION=`curl -sS chromedriver.storage.googleapis.com/LATEST_RELEASE` \
  && wget -N http://chromedriver.storage.googleapis.com/$CHROMEDRIVER_VERSION/chromedriver_linux64.zip -P ~/ \
  && unzip ~/chromedriver_linux64.zip -d ~/ \
  && rm ~/chromedriver_linux64.zip \
  && chown root:root ~/chromedriver \
  && chmod 755 ~/chromedriver \
  && mv ~/chromedriver /usr/bin/chromedriver \

ここでは ChromeDriver の最新版を取得、展開した後、指定の場所へ移動している。

署名を追加

ChromeDriver を使うために必要。

  && sh -c 'wget -q -O - https://dl-ssl.google.com/linux/linux_signing_key.pub | apt-key add -' \
  && sh -c 'echo "deb [arch=amd64] http://dl.google.com/linux/chrome/deb/ stable main" >> /etc/apt/sources.list.d/google-chrome.list'

Google の署名鍵をダウンロードしている。
そして、後述で google-chrome-stable をインストールしている。

System spec の準備

spec/supportフォルダの有効化

rails_helper.rb ファイル内の以下の記述をコメントアウト

Dir[Rails.root.join('spec/support/**/*.rb')].each { |f| require f }

** Capybaraの設定
>|ruby|
# spec/support/capybara.rb
Capybara.server = :puma, { Silent: true }

Capybara.register_driver :chrome_headless do |app|
  options = ::Selenium::WebDriver::Chrome::Options.new

  options.add_argument('--headless')
  options.add_argument('--no-sandbox')
  options.add_argument('--disable-dev-shm-usage')
  options.add_argument('--window-size=1400,1400')

  Capybara::Selenium::Driver.new(app, browser: :chrome, options: options)
end

Capybara.javascript_driver = :chrome_headless

# Setup rspec
RSpec.configure do |config|
  config.before(:each, type: :system) do
    driven_by :rack_test
  end

  config.before(:each, type: :system, js: true) do
    driven_by :chrome_headless
  end
end

以上でsystem specが作動するようになる。

参考記事
GitHub - progrium/entrykit: Entrypoint tools for elegant, programmable containers
RailsのDocker環境にEntrykitを導入し、bundle installを自動実行させる方法 | Enjoy IT Life
Entrykit のすすめ - Qiita
【rails】Docker環境でSystemSpecの導入の仕方。 - 技術系ブログ
RailsのSystemTest(headless chrome)をDocker上で動かす - Qiita
Rails + postgres + chromedriverのdocker-compose環境を作る - Qiita