docker (rocker) でheadless Chromeを動かす

by
カテゴリ:
タグ:

RでWebページのスクリーンショットを撮るにはheadless Chromeが今風?

従来、RでWebページのスクリーンショットを撮るにはwebshotパッケージが活躍してきました。しかし、webshotパッケージの内部で動くPhantomJSは開発が停止して久しいです。

そんな中、webshotパッケージの開発者であるwchは、headless Chromeを使ってスクリーンショットを撮影するwebshot2パッケージをRStudio製OSSとして開発開始しました。

現段階ではCRANに上がっていないので、インストールするにはremotes::install_github("rstudio/webshot2")を実行して下さい。

開発者が同じなだけあってwebshot2::webshot関数とwebshot::webshot関数の引数は同じです。と言うわけで使い方はぞうさんのページを参照して下さい(https://kazutan.github.io/kazutanR/webshot_demo.html)。

Dockerでheadless Chromeが動かない……!

さて、webshot2パッケージではchromoteパッケージを通じてheadless Chromeを動作させているわけですが、docker上で適当なページを撮影しようとすると、以下のようにエラーが返ります。

webshot2::webshot("https://google.com")
#> Error in launch_chrome(path, args) : 
#>  Failed to start chrome. Error: [0808/182701.557515:ERROR:zygote_host_impl_linux.cc(89)] Running asroot without --no-sandbox is not supported. Seehttps://crbug.com/638180.

どうやら--no-sandboxを指定すればよさそうですが、セキュリティを低下させるのでお勧めできません1

docker run時にsecurity_optを弄れば良いらしい

Issueにて解決を図ったところ、pagedownパッケージのドキュメントに記載されている通り、 https://raw.githubusercontent.com/jessfraz/dotfiles/master/etc/docker/seccomp/chrome.json からJSONをダウンロードして、以下のようにdocker runすれば良いと教えてもらいました2

docker run -e PASSWORD=yourpassword --rm -p 8787:8787 --security-opt seccomp="$(pwd)/chrome.json" myimages/pagedown

docker-composeでできるようにしよう

上述の方法で解決できましたが、コマンド入力が面倒なので、 docker-composeでできるようにしました。

  1. 先述のJSONをchrome.jsonとして保存

  2. 同ディレクトリにdocker-compose.ymlを用意(適宜編集して下さい)

    version: "3"
    services:
      r:
        image: atusy/atusydown
        ports:
          "8787:8787"
        environment:
          - ROOT=TRUE
          - USER=rstudio
          - PASSWORD=password
        security_opt:
          - seccomp:chrome.json
  3. sudo docker-compose up -dを実行

Docker imageとしてオリジナルのatusy/atusydownを用いていますが、 webshot2パッケージ以外にも色々入っていて重いです。任意のものを用意して頂いて結構ですが、 chromiumとwebshot2パッケージをインストールした上で、RenvironCHROMOTE_CHROME=/usr/bin/chromiumなどと記述して下さい。

Enjoy!


  1. 無理矢理--no-sandboxする方法はこちらに記述しました(https://github.com/rstudio/chromote/issues/20)。アイディアを提供して下さったyutannihilation氏に感謝します。↩︎

  2. pagedownのissueを置いかけると、headless Chromeを動かしてる既存のDockerイメージを参考にすれば良いという当たり前なことがわかり、リサーチ不足っぷりを反省しました(justinribeiro/chrome-headless)。↩︎