Dockerで日本語対応のPuppeteerを動かす
Dockerを使ってPuppeteerを動かせるようにした。
日本語ページを開く際に文字化けしたので日本語フォントをインストールして対応した。
package.jsonにpuppeteerを追加。
{
"name": "puppeteer_sample",
"version": "1.0.0",
"main": "index.js",
"dependencies": {
"puppeteer": "^1.20.0"
},
"scripts": {
"start": "node index.js"
}
}
空のyarn.lockを追加しておく。
touch yarn.lock
Dockerfileに以下を記述。
# Dockerfile
FROM alpine:edge
RUN apk update
# japanese font
RUN apk add --no-cache curl fontconfig font-noto-cjk \
&& fc-cache -fv
# Installs latest Chromium (76) package.
RUN apk add --no-cache \
chromium \
nss \
freetype \
freetype-dev \
harfbuzz \
ca-certificates \
ttf-freefont \
nodejs \
yarn
# timezone
RUN apk add --update --no-cache tzdata && \
cp /usr/share/zoneinfo/Asia/Tokyo /etc/localtime && \
echo "Asia/Tokyo" > /etc/timezone && \
apk del tzdata
# Tell Puppeteer to skip installing Chrome. We'll be using the installed package.
ENV PUPPETEER_SKIP_CHROMIUM_DOWNLOAD true
COPY ./package.json /app/package.json
COPY ./yarn.lock /app/yarn.lock
RUN yarn
# Add user so we don't need --no-sandbox.
RUN addgroup -S pptruser && adduser -S -g pptruser pptruser \ && mkdir -p /home/pptruser/Downloads /app \
&& chown -R pptruser:pptruser /home/pptruser \
&& chown -R pptruser:pptruser /app
# Run everything after as non-privileged user.
USER pptruser
WORKDIR /app
CMD ["yarn", "start"]
docker-compose.ymlはこんな感じ。
# docker-compose.yml
version: "3.3"
services:
datastore:
image: busybox
volumes:
- node_modules:/usr/local/lib/node_modules
app:
build: .
working_dir: "/app"
tty: true
stdin_open: true
volumes:
- node_modules:/usr/local/lib/node_modules
- .:/app
shm_size: 256
cap_add: # https://github.com/GoogleChrome/puppeteer/blob/master/docs/troubleshooting.md#tips
- SYS_ADMIN
volumes:
node_modules:
datastoreにnode_modulesをインストール。
docker-compose run app yarn
あとはpuppeteerを呼び出すコードを書けばDocker上で自由に試せる。
const puppeteer = require('puppeteer');
(async() => {
const browser = await puppeteer.launch({
executablePath: "/usr/bin/chromium-browser"
});
const page = await browser.newPage();
await page.goto('http://example.com');
await page.screenshot({path: 'example.png'});
await browser.close();
})();