docker-compose+puppeteerですぐに開発できるイメージを構築【日本語対応】
2019.10.24 更新
詳しい原因がまだわかっていないのですが、 alpine:edge
を指定していると正常にChromiumが立ち上がらない状態になっていることを確認したため一時的に alpine:latest
を指定するように記事を修正しました。 この変更により日本語フォントをシンプルにインストールできなくなっています(タイトル詐欺ですみません)。
puppeteerのREADMEが更新されていたので記事内のバージョンも1.17.0から1.19.0に更新しました。
- Dockerfile / docker-compose.yml は最小限自分で書く・引用する場合は引用元を明確にし、最新の情報へアップグレードできるようにする
- ローカル環境を汚したりせずコンテナに入って
webpack --watch
しながらnode
ですぐ動作確認したい- クラウドサービスへデプロイできるようにもしたい
※Dockerの知識は2018年末ぐらいで止まっているので一部古い情報の可能性があります
(最終的な)ディレクトリ構成
-
app
ソースコードなどビルドに必要なファイルのディレクトリ
-
dist
ビルド済みファイル
-
src
ソースコード
- index.ts
- package.json
- tsconfig.json
- webpack.config.js
- yarn.lock
-
shared
コンテナと双方向で共有するディレクトリ、今回はスクショ撮ったらローカルで見たいので用意(用途によっては不要)
- .dockerignore
- docker-compose.yml
- Dockerfile
まずはDockerfile
ソースコードなどビルドに必要なファイルのディレクトリ
-
dist
ビルド済みファイル
-
src
ソースコード
- index.ts
- package.json
- tsconfig.json
- webpack.config.js
- yarn.lock
コンテナと双方向で共有するディレクトリ、今回はスクショ撮ったらローカルで見たいので用意(用途によっては不要)
手短な方法を探しましたが公式的にはおまじないが必要そうです。トラブルシューティングにある Alpine を利用しました。
################################################################################
# https://github.com/GoogleChrome/puppeteer/blob/master/docs/troubleshooting.md
################################################################################
# FROM alpine:edge # 2019/10/24 Chromiumが起動できなくなったので使用しない
FROM alpine:latest
# Installs latest Chromium (77) package.
RUN apk add --no-cache \
chromium \
nss \
freetype \
freetype-dev \
harfbuzz \
ca-certificates \
ttf-freefont \
nodejs \
yarn
# Tell Puppeteer to skip installing Chrome. We'll be using the installed package.
ENV PUPPETEER_SKIP_CHROMIUM_DOWNLOAD true
# Puppeteer v1.19.0 works with Chromium 77.
RUN yarn add [email protected]
# 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 ["sh"]
###
で囲まれている部分は引用で最後の数行だけオリジナルです。appをカレントディレクトリとしてshが立ち上がるようにします。
puppeteerがyarn推しなのでnpmが使いたい場合はyarnになっている部分を適宜修正してください。
/app
のディレクトリ名を変える場合、上記chownしている部分も変える必要がありそうです
日本語ページをレンダリングしたい場合は下記追加してください
ttf-freefont \
nodejs \
- yarn
+ yarm \
+ font-noto-cjk # (現時点では alpine:edge で使用可能)
+ unifont # (alpine:latest でも使用可能)
docker-compose.yml
version: '3'
services:
app:
privileged: true
build: .
volumes:
- ./shared:/shared
- ./app:/app
version: '3'
services:
app:
privileged: true
build: .
volumes:
- ./shared:/shared
- ./app:/app
privileged: true
がないとうまく動きません
package.json とインストール
コンテナに入って作っていきます。よかったらこちらの記事も参照ください。
$ docker-compose build --no-cache # 初回は下記で実行されるので不要、--no-cacheはうまく反映されなくなったらつけてください
$ docker-compose run --rm app # ビルド済みコンテナに入る
...
/app $ whoami # 一応コンテナに入ったことを確認
pptruser # どーん
/app $ yarn init -y # とりあえず package.json を作成
...
/app $ yarn add --dev typescript webpack webpack-cli ts-loader @types/puppeteer
...
ソースコードを書く
tsconfig.json を作っておきます
/app $ ./node_modules/.bin/tsc --init
続いて app/src/index.ts を作ります。コード自体はありきたりなので特に触れません。
import puppeteer from 'puppeteer';
(async () => {
try {
const browser = await puppeteer.launch({
executablePath: '/usr/bin/chromium-browser',
args: ['--disable-dev-shm-usage']
}); // オプションはトラブルシューティング参照
const page = await browser.newPage();
await page.goto('https://qiita.com/');
await page.screenshot({
path: '/shared/result.png'
});
} catch (e) {
console.error(e);
}
})();
実行できるようにする
package.json に scripts を追加します
{
"name": "app",
"version": "1.0.0",
- "main": "index.js",
+ "main": "dist/main.js",
"license": "MIT",
+ "scripts": {
+ "build": "webpack",
+ "start": "webpack --watch --progress"
+ },
"devDependencies": {
"@types/puppeteer": "^1.20.1",
"ts-loader": "^6.2.0",
"typescript": "^3.6.3",
"webpack": "^4.41.0",
"webpack-cli": "^3.3.9"
}
}
webpack の設定がまだだったので作ります、 webpack init
は色々遠回りだったので調整済みの設定を貼ります
const path = require('path');
const webpack = require('webpack');
module.exports = {
mode: 'development',
entry: './src/index.ts',
output: {
filename: '[name].js',
path: path.resolve(__dirname, 'dist')
},
plugins: [new webpack.ProgressPlugin()],
module: {
rules: [
{
test: /.(ts|tsx)$/,
include: [path.resolve(__dirname, 'src')],
loader: 'ts-loader'
}
]
},
resolve: {
modules: ['node_modules'],
extensions: ['.ts', '.js']
},
target: 'node'
};
最後のtargetだけ指定しておかないとエラーで起動できなくなります
実行
/app $ yarn start
/app $ yarn start
でビルドしつつwatchが始まります。別のシェルを起動してそちらで都度nodeを呼び出すと実行されるわけですが、dockerを使ってるとちょっとだけ面倒です。
$ docker ps # コンテナIDを確認するために表示
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
9721b1846c11 puppeteer-tool_app "sh" 7 minutes ago Up 7 minutes puppeteer-tool_app_run_753be0a1576d
$ docker exec -it 9721b1846c11 /bin/sh # コンテナに入ってシェル起動
/app $ node . # 実行!
これで /dist に result.png が出来上がっているはずです。
デプロイ用イメージに切り替える
上記は開発用ですがクラウドで使用したい場合はコンテナを起動するだけで実行してほしいはずです。下記のように変更します。
Dockerfile
+ COPY app app
WORKDIR /app
+ RUN yarn install && yarn build
- CMD ["sh"]
+ CMD ["node", "."]
docker-compose.yml
app:
privileged: true
build: .
volumes:
- ./shared:/shared
- - ./app:/app
app/dist
や app/node_modules
は不要なので .dockerignore をプロジェクトのルートディレクトリに設置しておきましょう
app/dist
app/node_modules
下記でシェルには入らず実行後終了されるはずです。
$ docker-compose build
...
$ docker-compose up
このパターンだと試行錯誤しながら開発しづらいので最終段階になったら変更するのが良さそうです。
参考にした記事
https://qiita.com/EBIHARA_kenji/items/31b7c1c62426bdabd263
https://qiita.com/sekizo/items/27cc9b406332afc674f6
Author And Source
この問題について(docker-compose+puppeteerですぐに開発できるイメージを構築【日本語対応】), 我々は、より多くの情報をここで見つけました https://qiita.com/cubenoy22/items/4fa2d578abf2b72be389著者帰属:元の著者の情報は、元のURLに含まれています。著作権は原作者に属する。
Content is automatically searched and collected through network algorithms . If there is a violation . Please contact us . We will adjust (correct author information ,or delete content ) as soon as possible .