背景
Dockerコンテナ上のpuppeteerでE2Eテストを各環境ごとでやる場合、
環境変数をどうやってうまいことセットすれば良いのか、検証した
状況
puppeteerが目的のサイトにアクセスしてなんやかんやテストするスクリプトを書きたい
↓
開発環境とかステージング環境とか本番環境とかで違う変数を簡単に定義したいなあ
↓
node-configっていうのが便利なのか
↓
全部あわせてDockerに組み込んでみよう
縛り
docker-compose build
で、puppetterやnode-configがインストールされ
docker-compose up
でdockerが立ち上がり、テストする、という流れは崩さない。
なんか別にコマンド使ったり設定変えるたびに毎回コンテナをbuildしたりはしない。
やり方
FROM node:9.10.0
RUN apt-get update \
&& apt-get install -y \
gconf-service \
libasound2 \
libatk1.0-0 \
libc6 \
libcairo2 \
libcups2 \
libdbus-1-3 \
libexpat1 \
libfontconfig1 \
libgcc1 \
libgconf-2-4 \
libgdk-pixbuf2.0-0 \
libglib2.0-0 \
libgtk-3-0 \
libnspr4 \
libpango-1.0-0 \
libpangocairo-1.0-0 \
libstdc++6 \
libx11-6 \
libx11-xcb1 \
libxcb1 \
libxcomposite1 \
libxcursor1 \
libxdamage1 \
libxext6 \
libxfixes3 \
libxi6 \
libxrandr2 \
libxrender1 \
libxss1 \
libxtst6 \
ca-certificates \
fonts-liberation \
fonts-ipafont \
fonts-ipaexfont \
libappindicator1 \
libnss3 \
lsb-release \
xdg-utils \
wget \
&& npm i config puppeteer
WORKDIR /app
CMD bash /app/start.sh
version: '3'
services:
puppeteer:
build: .
container_name: "puppeteer"
working_dir: "/opt/data-volume"
volumes:
- .:/opt/data-volume
- ./script.js:/app/script.js
- ./start.sh:/app/start.sh
tty: true
stdin_open: true
上記のようにdockerの準備をする
Dockerfileに色々書いていますが、大半がpuppeteerのためのもので(たぶん)
ミソは最後のCMD bash /app/start.sh
これで以下のシェルを実行している
#!/bin/bash
export NODE_ENV=development
node /app/script.js
node-configにどの環境のファイルを読むかを指定している
これで、起動するとbuild時に指定しておいたCMD bash /app/start.sh
が実行され
以下のpuppeteer稼働用のscript.jsを実行する
そう、環境変数をセットするため、start.shを挟んだということです。
var config = require('config');
console.log("NODE_ENV=%s", process.env.NODE_ENV);
console.log(JSON.stringify(config));
const puppeteer = require('puppeteer');
(async () => {
const browser = await puppeteer.launch({
args: [
'--no-sandbox',
'--disable-setuid-sandbox'
]
});
const page = await browser.newPage();
await page.goto(config.url, {waitUntil: 'networkidle0'}); //ここでconfigでセットしたものが入る
await console.log('access top');
await page.screenshot({ path: 'top.png'});
browser.close();
})();
で、以下のようなjsonで書かれた環境ごとのファイルが読み込まれる
{
"message": "This is a default config",
"user": "user",
"password": "password",
"url": "https://dev.example.com/"
}
これで、例えば本番の設定を呼びたいときなどは
start.shの
export NODE_ENV=development
を
export NODE_ENV=production
などに変えてやればいい
そうすればdocker-compose up
時に以下のように別に用意しているproduction.jsonが呼ばれることになる
{
"message": "This is a production config",
"user": "user",
"password": "password",
"url": "https://prd.example.com/"
}
雑感
何でもかんでも実行をシンプルにしておくと、「これどうやって使うんだっけ?」がなくなるんで便利。
コマンドの引数で制御してやればもっと楽になるやも。
puppeteerのシナリオ書くの面倒。(今回関係ないけど)