Puppeteerの実行エラー
puppeteerのJestサンプルをTypeScriptで書いて動かそうとしたら、コンテナ側のライブラリ不足エラーが出たので対処していました。
エラー内容
動かそうとしたサンプルは以下で、Dockerコンテナのベースはnode:14-slimです。
これを実行すると以下のようなerror while loading shared libraries
のエラーが表示されます。
エラーをメモしてなかったので、検索履歴から引っ張ってきたものですが、こんな感じのエラーが出ていました。 実際にはエラーは1つずつしか出ないので、都度apt-get installしていました。(見やすく改行や加工をしています)
error while loading shared libraries: libatk-bridge-2.0.so.0: cannot open shared object file: No such file or directory libgobject-2.0.so.0: cannot open shared object file: No such file or directory libnss3.so: cannot open shared object file: No such file or directory libasound.so.2: cannot open shared object file: No such file or directory
実行環境
動作時の主なライブラリのバージョンは以下のとおりです。
- puppeteer: 5.3.1
- typescript: 4.0.3
- jest: 26.4.2
- node: 14.11.0(コンテナ node:14-slim)
不足しているライブラリの追加
以下のようにライブラリを入れるとエラーが消えます。
apt-get install -y libgtk-3.0 libgbm-dev libnss3 libatk-bridge2.0-0 libasound2
コンテナにはbuild-essentialも入れているので、もしかしたらこれも必要かもしれません。
ライブラリ不足解消後の問題
ライブラリ不足を解消してから実行すると、今度は以下のエラーが出たので、エラーメッセージの通り、--no-sandbox
を使って実行するように変更して解消しました。
Running as root without --no-sandbox is not supported. See https://crbug.com/638180
まとめ
Puppeteerをnode:14-slimのコンテナで使うためにはlibgtk-3.0 libgbm-dev libnss3 libatk-bridge2.0-0 libasound2
のライブラリをOSにインストールし、
TypeScriptの場合は以下のようなコードにする必要があります。
import { beforeAll, afterAll, describe, expect, test } from '@jest/globals'; import puppeteer, { Browser, Page } from 'puppeteer'; let browser: Browser; let page: Page; beforeAll(async () => { browser = await puppeteer.launch({ args: ['--no-sandbox'] }); page = await browser.newPage(); }); describe('Google Homepage', () => { test('has title "Google"', async () => { await page.goto('https://google.com', { waitUntil: 'networkidle0' }); const title = await page.title(); expect(title).toBe('Google'); }); afterAll(async () => { await browser.close(); }); });
追記
そもそもこのexamples配下のコードは非推奨になっているくさく、「theheadless.devの方を見てね」みたいなことがREADMEに書かれてますね。
あとちゃんとは見てないのですが、jestでの実行は以下を使うのが良いのかもしれないです。