shoetBlog
技術や好きなことについて発信しています。
AWS Lambda上でChromiumブラウザを動かす
2024/2/4 2:57:32
GoChormiumAWSLambda
AWS Lambda上でChromiumブラウザを動かす

先日投稿した、こちらのブログでECSタスク上でChromiumブラウザを使用し、
Webスクレイピングを行いましたが、AWS Lambda上でもできないか、実験しました。

言語はGoで進めましたが、 Go x Lambda x ブラウザ操作 の知見が Web上では少なかったため、試行錯誤が必要でした。

ブラウザ操作には、いろいろな環境などの制約もありPlaywright-goを使用しました。

結果的に以下の構成で実現できました。

1.LambdaはDockerイメージをビルドしGoプログラムを動かす

2.ブラウザ操作のライブラリにはPlaywright-goを使用する

3.ブラウザをDocker buildで/varにダウンロードしておき、Lambda起動直後に/var配下に移動させる

一つずつ説明していきます。

1. LambdaはDockerイメージをビルドしGoプログラムを動かす

Lambdaの実行環境にヘッドレスブラウザを用意します。

Playwright(※1)が提供している公式のDockerイメージをベースに構築しました。

Dockerfile

# ===== build stage ====
FROM golang:1.20.12-bullseye as builder

...<割愛>

# ===== deploy stage ====
FROM mcr.microsoft.com/playwright:v1.40.0-jammy as deploy

RUN apt update
RUN apt install -y golang-1.20
ENV GOPATH=/go
ENV GOROOT=/usr/lib/go-1.20
ENV PATH=$PATH:$GOROOT/bin:$GOPATH/bin

WORKDIR /app

RUN mkdir -p /var/playwright/browser
ENV PLAYWRIGHT_BROWSERS_PATH=/var/playwright/browser
RUN go run github.com/playwright-community/playwright-go/cmd/playwright@latest install --with-deps

COPY --from=builder /app/summarytask/bin/main ./main

CMD ["/app/main"]

2. ブラウザ操作のライブラリにはPlaywright-goを使用する

先述した通りブラウザの操作にはPlaywrightを使用し、それに対応したGoプログラムを作成しました。
また、PlaywrightでChormiumを起動する必要がありますが、そのオプションについて試行錯誤が必要でした。

Lambda環境ではブラウザの並列実行が許されていないのか、—single-processオプションの指定が必要な上、GPUに関するオプションの指定も必要でした。
playwright_crawler.go

3. ブラウザをDocker buildで/varにダウンロードしておき、Lambda起動直後に/var配下に移動させる

Playwrightはデフォルトでは/home/.cacheフォルダにブラウザに関する諸々をダウンロードしようとしますが、
Lambda環境では/tmp以外は使用できないため、Playwrightのオプションで/tmpフォルダを指定することと、
Dockerビルドの段階で/tmpへブラウザをダウンロードしてDockerイメージに固めておく必要があります。
Dockerfile

また、Lambdaは起動時に/tmp配下を掃除するような動きをするのか、 Lambda起動後にブラウザが見つからない旨のエラーが起きました。

そのため、イメージのビルドの段階では/var配下にブラウザをダウンロードし、 Lambdaが起動した直後に/varから/tmpへブラウザを移動するようにしました。
playwright_crawler.go

ソースコード

ソースコード全体は下記に共有します。
summarytask

コメント
profile
匿名ユーザー(ID: )
Markdown
Preview
エンジニア。
エンジニアリングで価値提供できるよう、
日々自己研磨。
AWSAWS LambdaChormiumCloudFrontDockerECSGitHubGoGraphQLLambdaLocalStackNext.jsOpenAIPlanetScaleReactReduxServerlessFrameworkTypeScriptUpstashViteWebSocket