Rails + postgres + chromedriverのdocker-compose環境を作る

RSpecでのFeature Specのためにはchromedriverが必要だが、docker-compose環境で実行するのは結構しんどかったのでまとめます。  
コードはこちらに記載しており、そのまま動かせるようになっています。
  
<https://github.com/MH4GF/rails-chromedriver-docker-compose>  
  
今回はDockerやdocker-composeに対する説明はせず、chromedriverに関することのみ紹介します。  

## 環境

```
ruby: 2.7.0
rails: 6.0.2.1
postgresql: 12.2
chromedriver: 80.0.3987.106
```

## TL;DR

1. chromeのインストール(署名が必要)
2. 依存ライブラリのインストール
3. インストールしたchromeのバージョンに合わせたchromedriverをインストール
4. rails_helper.rbにchromedriverの実行時オプションを追加

この4ステップが必要だった。  

## Dockerfile

docker-compose.ymlも用意しているので、詳しくは[リポジトリ](https://github.com/MH4GF/rails-chromedriver-docker-compose)をご覧ください。

```dockerfile:Dockerfile

FROM ruby:2.7.0

ENV LANG C.UTF-8
ENV TZ=Asia/Tokyo

WORKDIR /app

# nodejs, yarn, postgresql-clientをインストール
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 \
  && apt-get update -qq \
  && apt-get install -y nodejs yarn postgresql-client

# 署名を追加(chromeのインストールに必要) -> apt-getでchromeと依存ライブラリをインストール
RUN wget -q -O - https://dl-ssl.google.com/linux/linux_signing_key.pub | apt-key add \
  && echo 'deb [arch=amd64] http://dl.google.com/linux/chrome/deb/ stable main' | tee /etc/apt/sources.list.d/google-chrome.list \
  && apt-get update -qq \
  && apt-get install -y google-chrome-stable libnss3 libgconf-2-4

# chromedriverの最新をインストール
RUN CHROMEDRIVER_VERSION=`curl -sS chromedriver.storage.googleapis.com/LATEST_RELEASE` \
  && curl -sS -o /tmp/chromedriver_linux64.zip http://chromedriver.storage.googleapis.com/$CHROMEDRIVER_VERSION/chromedriver_linux64.zip \
  && unzip /tmp/chromedriver_linux64.zip \
  && mv chromedriver /usr/local/bin/

COPY Gemfile .
COPY Gemfile.lock .
RUN bundle install

COPY package.json .
COPY yarn.lock .
RUN yarn install

# rails serverはdocker-compose.ymlで起動する
```

## chromedriverに関連する記述を抜粋

### 署名を追加 -> apt-getでchromeと依存ライブラリをインストール

```dockerfile


RUN wget -q -O - https://dl-ssl.google.com/linux/linux_signing_key.pub | apt-key add \
  && echo 'deb [arch=amd64] http://dl.google.com/linux/chrome/deb/ stable main' | tee /etc/apt/sources.list.d/google-chrome.list \
  && apt-get update -qq \
  && apt-get install -y google-chrome-stable libnss3 libgconf-2-4
```

google-chrome-stableをインストールするためには署名が必要で、それを先にダウンロードしてやる必要がありました。
ここで同時に必要なライブラリもインストールしています。

### chromedriverの最新をインストール

```dockerfile

RUN CHROMEDRIVER_VERSION=`curl -sS chromedriver.storage.googleapis.com/LATEST_RELEASE` \
  && curl -sS -o /tmp/chromedriver_linux64.zip http://chromedriver.storage.googleapis.com/$CHROMEDRIVER_VERSION/chromedriver_linux64.zip \
  && unzip /tmp/chromedriver_linux64.zip \
  && mv chromedriver /usr/local/bin/
```

chromedriverは、対応するchromeとバージョンをあわせてインストールする必要があります。
<https://chromedriver.chromium.org/downloads>
より良い方法はバージョンを固定してインストールすべきですが、今回はそこまでせずともよいだろうと判断し最新バージョンをインストールすることにしました。  
ここではchromedriverをインストールしバイナリをパスの通った場所に移動しています。

## rails_helper.rbにchromedriverの実行時オプションを追加

まだこのままではCapybaraから実行することはできず、 `rails_helper.rb` に実行時オプションを追加する必要があります。

```ruby:rails_helper.rb
config.before(:each, type: :system) do
  driven_by :selenium, using: :headless_chrome, screen_size: [1920, 1080],
                       options: { args: %w[headless disable-gpu no-sandbox disable-dev-shm-usage] }
end

```

Docker環境は基本的にrootユーザーであり、rootでchromedriverを動かすためには `no-sandbox` オプションが必要となるためです。  
<https://developers.google.com/web/updates/2017/04/headless-chrome?hl=ja>  

そのためrspec側で明示的にオプションを追加しています。

これはローカル環境では不要なオプションで、Docker環境でのみ必要なオプションをrailsに追加するのは悲しいとは思っています。最初はDockerfileでadduserするなどでRails側には何も影響しないようにする方針で考えていました。  
しかし一般ユーザーに降格するとdocker-composeで作業中所々でsudoが必要になりそれもつらい。ローカル環境のrspecでも動作確認をしオプションを追加しても問題なく動くことを確認できているため、塩梅を取って今回はrails_helperを修正する形を取りました。  
皆さんどのように実行しているのでしょうか、、

## おわり

以上です。同じ苦しみを味わった方が参考になれば幸いです。マサカリ等もお待ちしております。
<https://github.com/MH4GF/rails-chromedriver-docker-compose>