やりたいこと
-
circleci/
ownerのdocker imageがdeprecatedになるようなので、新しいcimg/
に更新したい- seleniumでなんやかんやする目的で利用していたので
circleci/python-3.8.3-browsers
->cimg/python-3.9.10-browsers
あたりに更新したい
- seleniumでなんやかんやする目的で利用していたので
公式アナウンス
- https://discuss.circleci.com/t/legacy-convenience-image-deprecation/41034
- https://circleci.com/blog/announcing-our-next-generation-convenience-images-smaller-faster-more-deterministic
やったこと
dockerfile先頭のimage指定を差し替える
FROM circleci/python:3.8.3-browsers
↓
FROM cimg/python:3.9.10-browsers
sudo周りを修正する
pip周りの権限が微妙に変わっているようなのでsudoを外す。
apt-getなどはsudo付きのままでよい模様。
RUN sudo pip install --upgrade pip \
&& sudo pip install -r ./requirements.txt
↓
RUN pip install --upgrade pip \
&& pip install -r ./requirements.txt
ホームディレクトリでふんわりやっている処理を絶対パスに差し替える
詳しい仕様が分からないのでアレだが、どうもdockerfile内とコンテナ起動後のユーザーが違うらしく、ビルド中とビルド後でホームディレクトリのパスが異なるっぽい。
なので明示的に指定するようにした。
WORKDIR ~
RUN sudo git clone https://github.com/wolfcw/libfaketime.git
WORKDIR /libfaketime
RUN sudo make install
WORKDIR /home/circleci
RUN git clone https://github.com/wolfcw/libfaketime.git
WORKDIR /home/circleci/libfaketime
RUN make
ちなみに導入しているのはlinux/mac環境でシステム時間をいじることができるライブラリ。
https://github.com/wolfcw/libfaketime
google chromeをインストールする
circleci/
のときは x-browsers
タグを指定するとブラウザも導入済の状態で提供されていたので、インストールが必要なことに驚いた。
ブラウザー バリアントのベースは元の Python イメージと同一ですが、こちらでは apt により Node.js、Java、Selenium、ブラウザーの依存関係が事前インストールされます。 使用するには、-browser を既存の cimg/python タグの末尾に追加します。 このバリアントは、CircleCI Browser-Tools Orb と組み合わせて使用する想定で設計されています。 この Orb を使用すると、任意のバージョンの Google Chrome と Firefox のいずれかまたは両方をビルドでインストールできます。
circleciの想定ではそもそもこのimageは docker executor で利用する前提であり、 browser-tools/install-browser-tools
というcircleci謹製orbsを使うことでイメージサイズの縮小を狙っていると思われる。
今回はmachine executor上で動くコンテナのベースイメージとして利用する。
依存関係やseleniumなどは導入済・実態はUbuntu20.04なのでおとなしく手動インストールしていく。
WORKDIR /home/circleci
RUN wget https://dl.google.com/linux/linux_signing_key.pub \
&& sudo apt-key add linux_signing_key.pub \
&& echo 'deb [arch=amd64] http://dl.google.com/linux/chrome/deb/ stable main' | sudo tee /etc/apt/sources.list.d/google-chrome.list \
&& sudo apt -y update && sudo apt-get -y install google-chrome-stable
linux_signing_key.pub
というファイルが生成されるので、マウントされたボリュームじゃない場所でやるとよい。
tips:コンテナ全体の中でseleniumで起動したchromeのみにlibfaketimeを適用する
通常libfaketimeを利用する場合、docker-compose.ymlなどで環境変数 FAKETIME='2022-01-01 12:00:01
のように設定することになる。
が、こうすると同じコンテナ内で動作させたサーバーなどが証明書エラーで実行できなくなるケースがあるため、selenium chromeのみにlibfaketimeを適用する手法を紹介する。
少なくともubuntuでは、/usr/bin/chrome
(chrome本体のバイナリ)ではなく/usr/bin/google-chrome
(シェルスクリプト)経由でgoogle chromeを実行する構造になっている。
(直接起動するときもseleniumから起動するときも同じ)
そのため、この /usr/bin/google-chrome
に以下のような行を追加すればgoogle chromeのみlibfaketime環境を適用することができる。
export FAKETIME=$FAKETIME_FOR_BROWSER
seleniumからchromeを起動する際のオプションにdevtoolsのポート設定を追加する
自分の環境では無かったらエラーが出てあるとエラーが消えたので一応。
環境によっては無くてもいいはず。ポートはコンテナ内で衝突しないように注意。
options.add_argument("--remote-debugging-port=9222")
ついでなので現在適用している他の設定も紹介しておく。
--disable-dev-shm-usage
などの安定すると言われているオプションなどは色々試した結果あってもなくても変わらないということが分かっている。
options = selenium.webdriver.ChromeOptions()
options.add_argument('--headless')
options.add_argument("--remote-debugging-port=9222")
options.add_experimental_option('excludeSwitches', ['enable-automation'])
# ssl証明書エラーの回避
capabilities = DesiredCapabilities.CHROME.copy()
capabilities['acceptInsecureCerts'] = True
まとめ
circleci/
-> cimg/
への移行はそこまで互換性があるわけではなく、まあまあに対処すべきことが多いので、時間作ってさっさとやるべき