はじめに
フルスタックなJavaエンジニアでした。訳あってPHPerをやっています。
AWSでCIないのかなーと思っていたら、 Cloudwatch Synthetics Canaries
というものがあったので、チャレンジ中です。
詳しいことを理解せず構築しているので、ふーん、位で見てもらえたら嬉しいです。
不定期に更新するかもです。
何がしたい?
Canariesで作って動かして、失敗して、を繰り返しすぎて嫌になってきた(特にお金とデプロイ時間が)ので、ローカルでなんとかならんかなーと試したメモです
このメモが読めそうな人
- Dockerわかる
- Puppeteerに触れている
前提、環境
- Puppeteer
4.0
- Node.js
18.16.0
- Docker
Docker version 23.0.4, build f480fb1
準備
ディレクトリ構成
./
|- Dockerfile
|- scripts
| |- modules
| | `- wrapper
| | `- aws
| | `- synthetics.js
| |- package.json
| |- sample.js
| `- script.js
`- outputs
modules
は、独自関数?的なものを置いていきます。
Synthetics
の executeStep
を Wrapper Mock として定義しています
outputs
にスクショを出します。
実行ログとかも出せると思いますが、未トライなのでいずれメモを追加します。いずれ。たぶん、きっと。
Dockerfile
FROM node:18.16.0-slim
WORKDIR /app
COPY ./scripts/package.json /app/package.json
WORKDIR /app
RUN apt-get update \
&& apt-get upgrade \
&& apt-get install -y \
libappindicator1 \
fonts-liberation \
chromium \
&& npm install --force
ENV NO_SANDBOX=true \
PUPPETEER_SKIP_CHROMIUM_DOWNLOAD=true \
PUPPETEER_EXECUTABLE_PATH=/usr/bin/chromium
CMD ["script.js"]
このまま docker run
すると、script.js
が実行されます
package.json
AWSに合わせて?? puppeteer 4.0
をインストールします。
間違ってる気がとてもとてもする・・・(2023/05/11時点で、puppeteerの最新が 20.1.2
なので。。。)
{
"dependencies": {
"puppeteer": "4.0"
}
}
synthetics.js
let page;
let output_dir = '/output/';
exports.setPage = async function (val) {
page = val;
}
exports.setOutputDir = async function (val) {
output_dir = val;
}
exports.executeStep = async function (label, callback) {
await page.screenshot({ path: output_dir + label + "_" + (new Date()).getTime() + ".png", fullPath: true });
await callback();
await page.screenshot({ path: output_dir + label + "_" + (new Date()).getTime() + ".png", fullPath: true });
}
スクリーンショットの保存先は、 /output/
で、ホストの ./outputs/
に吐き出されます。
一応、ファイルが重複しないように、ファイル名の後ろに、ミリ秒をくっつけています。
重複したらごめんね。
sample.js
ほかサイトに記載されていたサンプルをいじっています。著作権、ごめん。
const puppeteer = require('puppeteer');
const synthetics = require('./modules/wrapper/aws/synthetics');
(async () => {
const browser = await puppeteer.launch({
args: [
'--no-sandbox',
'--disable-setuid-sandbox'
]
});
const page = await browser.newPage();
synthetics.setPage(page);
await synthetics.executeStep('jikken', async function (timeoutInMillis = 30000) {
await page.goto('https://example.com');
await page.screenshot({ path: '/output/example.png', fullPath: true });
});
browser.close();
})();
synthetics.executeStep
を実行すると、スクリプト前後でスクリーンショットを撮ります。
サンプルの例だと、スクリプト内でも example.png
のスクショを撮っているので、 ./outputs
配下に3枚の画像が出てきますね。
AWSと異なるところは、処理の実行の仕方と、 page
の作り方・設定の所です。
本物のスクリプトと比較して、いい感じに環境別に動くようにすると、開発環境でもCanaries上でも同じスクリプトで動かせるかなーと思います。
実行
docker build -t puppeteer --no-cache ./
docker run --rm -it \
-v ./scripts:/app \
-v ./outputs:/output \
-w /app \
puppeteer
script.js
以外を実行する時は
docker run --rm -it \
-v ./scripts:/app \
-v ./outputs:/output \
-w /app \
puppeteer \
sample.js
の様に、container namerの後ろに、work dir配下にある(多分、相対パスでもOKだと思いますが)スクリプト名をつければOKです