Puppeteer を Cloud Run で動かすまで

Puppeteer を Cloud Run で動かすまで

December 1, 2023

ローカルで正常に機能していた Puppeteer ですが、Cloud Run にデプロイした後はエラーが出てしまい動かなくなりました。対応した手順のメモ書きです。

デプロイ直後に出たエラー #

Could not find Chrome (ver. 121.0.6167.85). This can occur if either
 1. you did not perform an installation before running the script (e.g. `npx puppeteer browsers install chrome`) or
 2. your cache path is incorrectly configured (which is: /home/node/.cache/puppeteer).
For (2), check out our guide on configuring puppeteer at https://pptr.dev/guides/configuration.

エラーで動かないのは残念ながらも、親切にも対応方法を案内してくれています。

対応

まずブラウザをインストールする必要があります。言われてみると確かに、ローカル環境だと自然と Chrome は入っているでしょうが、サーバ上では明示的にインストールしない限り Chrome は存在しません。

ということで、Dockerfile に次のコマンドを追加して Chrome をインストールするようにしましょう。

RUN npx puppeteer browsers install chrome

さらにキャッシュディレクトリの設定を行う必要があります。(参照:https://pptr.dev/guides/configuration#changing-the-default-cache-directory)

公式のガイドに従って .puppeteerrc.cjs を配置するようにしましょう。

const { join } = require('path');

/**
 * @type {import("puppeteer").Configuration}
 */
module.exports = {
  // Changes the cache location for Puppeteer.
  cacheDirectory: join(__dirname, '.cache', 'puppeteer'),
};
COPY .puppeteerrc.cjs ./
RUN npx puppeteer browsers install chrome

補足

.puppeteerrc.cjs の追加によって、逆にローカル環境で Puppeteer の処理を実行したときに新たにエラーになるかもしれません。そのような場合は、例えば Production 環境でのみキャッシュディレクトリの指定を行うようにすることで回避可能です。

const { join } = require('path');

/**
 * @type {import("puppeteer").Configuration}
 */
module.exports =
  process.env.NODE_ENV !== 'production'
    ? {}
    : {
        // Changes the cache location for Puppeteer.
        cacheDirectory: join(__dirname, '.cache', 'puppeteer'),
      };

上記対応後に出たエラー #

ここまでの対応を行った後で再度デプロイしたところ、次は以下のエラーが出るようになりました。

Failed to launch the browser process! undefined
/usr/.cache/puppeteer/chrome/linux-121.0.6167.85/chrome-linux64/chrome: error while loading shared libraries: libgobject-2.0.so.0: cannot open shared object file: No such file or directory

TROUBLESHOOTING: https://pptr.dev/troubleshooting

メッセージを見ると Chrome が必要とする依存関係が不足しているようです。サーバで使っている OS に応じて必要な依存関係をインストールするようにしましょう。(参照:https://pptr.dev/troubleshooting#chrome-doesnt-launch-on-linux)

Debian 12(Bookworm)の場合だと以下の依存関係をインストールすれば大丈夫でした。

RUN apt-get update && apt-get install -y \
  libasound2 \
  libatk-bridge2.0-0 \
  libatk1.0-0 \
  libc6 \
  libcairo2 \
  libcups2 \
  libdbus-1-3 \
  libexpat1 \
  libfontconfig1 \
  libgbm1 \
  libgcc1 \
  libglib2.0-0 \
  libgtk-3-0 \
  libnspr4 \
  libnss3 \
  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 \
  lsb-release

COPY .puppeteerrc.cjs ./
RUN npx puppeteer browsers install chrome

上記を加えてもまだ依存関係が足りないと言われるかもしれません。そのような場合は、不足している依存関係をさらに追加しても良いですが、もしかしたら --no-sandbox 指定で Puppeteer を使用するように変え、必要となる依存関係を減らすことで解消できるかもしれません。(参照:https://pptr.dev/troubleshooting#running-puppeteer-on-heroku)

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

終わり #

ここまでくれば Puppeteer が起動するようになっているのではないでしょうか?

その他参考