LoginSignup
28
21

More than 5 years have passed since last update.

Puppeteer をDockerコンテナで利用する

Last updated at Posted at 2017-09-07

Webサイトのスクリーンショットを取るCLIツールsite-checkerを作った。

インストール方法を書いていて、「Node.jsのvX.X.X以上をインストールして下さい」というのも今日的ではないなぁと感じて、実行環境のバージョンを気にせず利用できるようDockerイメージも用意した。その際、ちょっと引っかかったことを書く。

利用バージョン

Dockerfileの作成

最終的に作成したDockerfileは次の通り。

FROM node:8.4
MAINTAINER HeRoMo

RUN echo 'deb http://ftp.jp.debian.org/debian jessie-backports main' >> /etc/apt/sources.list
RUN set -ex; \
        apt-get update; \
        apt-get install -y --no-install-recommends \
                gconf-service \
                libasound2 \
                libatk1.0-0 \
                libc6 \
                libcairo2 \
                libcups2 \
                libdbus-1-3 \
                libexpat1 \
                libfontconfig1 \
                libgcc1 \
                libgconf-2-4 \
                libgdk-pixbuf2.0-0 \
                libglib2.0-0 \
                libgtk-3-0 \
                libnspr4 \
                libpango-1.0-0 \
                libpangocairo-1.0-0 \
                libstdc++6 \
                libx11-6 \
                libx11-xcb1 \
                libxcb1 \
                libxcomposite1 \
                libxcursor1 \
                libxdamage1 \
                libxext6 \
                libxfixes3 \
                libxi6 \
                libxrandr2 \
                libxrender1 \
                libxss1 \
                libxtst6 \
                ca-certificates \
                fonts-liberation \
                libappindicator1 \
                libnss3 \
                lsb-release \
                xdg-utils \
                wget \
                fonts-noto-cjk

RUN yarn global add site-checker

RUN mkdir -p /output
WORKDIR /output
ENV NO_SANDBOX=true
ENTRYPOINT [ "site-checker" ]
CMD [ "-h" ]

この内容になる前に次の3点の問題が発生した。

  • Puppeteerのインストールでエラーが発生
  • Chromeが起動できない
  • 日本語の文字が化ける

これらについて以下に述べる。

Puppeteerのインストールでエラーが発生

Puppeteerリポジトリのtroubleshooting.mdに依存パッケージの一覧があるのでそれらをapt-getでインストールする。そして、RUN npm install -g site-checker すれば良いと思ったのだが、ここで次のようなエラーが発生した。

> puppeteer@0.10.2 install /usr/local/lib/node_modules/site-checker/node_modules/puppeteer
> node install.js

fs.js:891
  return binding.mkdir(pathModule._makeLong(path),
                 ^

Error: EACCES: permission denied, mkdir '/usr/local/lib/node_modules/site-checker/node_modules/puppeteer/.local-chromium'
    at Object.fs.mkdirSync (fs.js:891:18)
    at Object.downloadRevision (/usr/local/lib/node_modules/site-checker/node_modules/puppeteer/utils/ChromiumDownloader.js:97:10)
    at Object.<anonymous> (/usr/local/lib/node_modules/site-checker/node_modules/puppeteer/install.js:33:12)
    at Module._compile (module.js:573:30)

    at Object.Module._extensions..js (module.js:584:10)
    at Module.load (module.js:507:32)
    at tryModuleLoad (module.js:470:12)
    at Function.Module._load (module.js:462:3)
    at Function.Module.runMain (module.js:609:10)
    at startup (bootstrap_node.js:158:16)
npm info lifecycle puppeteer@0.10.2~install: Failed to exec install script
npm ERR! code ELIFECYCLE
npm ERR! errno 1
npm ERR! puppeteer@0.10.2 install: `node install.js`
npm ERR! Exit status 1
npm ERR!
npm ERR! Failed at the puppeteer@0.10.2 install script.
npm ERR! This is probably not a problem with npm. There is likely additional logging output above.

npm installがダメなら、RUN yarn global add site-checker にしてみようと試すと、インストールに成功した。

Chromeが起動できない

イメージのビルドには成功して、次のように実行した。

docker run --rm -v $(pwd):/output:rw site-checker -u http://qiita.com/

すると次のようなエラーが発生した。

Error: Failed to launch chrome!
[0907/150437.316459:ERROR:zygote_host_impl_linux.cc(88)] Running as root without --no-sandbox is not supported. See https://crbug.com/638180.



TROUBLESHOOTING: https://github.com/GoogleChrome/puppeteer/blob/master/docs/troubleshooting.md

    at Interface.onClose (/usr/local/share/.config/yarn/global/node_modules/puppeteer/lib/Launcher.js:142:14)
    at emitNone (events.js:110:20)
    at Interface.emit (events.js:207:7)
    at Interface.close (readline.js:367:8)
    at Socket.onend (readline.js:147:10)
    at emitNone (events.js:110:20)
    at Socket.emit (events.js:207:7)
    at endReadableNT (_stream_readable.js:1059:12)
    at _combinedTickCallback (internal/process/next_tick.js:138:11)
    at process._tickCallback (internal/process/next_tick.js:180:9)

「Running as root without --no-sandbox is not supported.」と書いてあるので、rootでないユーザで実行してみたが、それでもエラーが発生する。

troubleshooting.mdを見よと示されているので参照すると、「try running without the sandbox」と書いているので、従うことにする。
Chromeを起動するときに次のように引数を与えれば良いらしい。

const browser = await puppeteer.launch({args: ['--no-sandbox', '--disable-setuid-sandbox']});

troubleshooting.md には--no-sandboxでの実行はセキュリティ的に推奨しないと書かれているが、Dockerコンテナの中なので割り切ることとした。

環境変数NO_SANDBOXで切り替えられるようにツールの実装を変更して対応した。

日本語の文字が化ける

なんとか動くようになったものの、日本語のサイトのスクリーンキャプチャを取ると次のように日本語が表示できなかった。

capture_00000s.png

日本語を表示できるフォントがイメージにインストールされてないからなのねと思い至り、Google Noto Fontsのインストールを追加した。

Nodeの公式イメージのOSであるdebian jessieのパッケージリポジトリにはないため、次のようにリポジトリを追加してapt-getでインストールした。

RUN echo 'deb http://ftp.jp.debian.org/debian jessie-backports main' >> /etc/apt/sources.list

すると次のように見事表示されるようになった。

capture_00000s.png

28
21
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
28
21