概要
- 10章 スケーラビリティとアーキテクチャ
- 10.2 クローニングと負荷分散
上記のサンプルコードを試すために、dockerを使ったところ、少しハマったのでメモ。
環境
- Windows 10
- Vagrant 2.2.5
- virtualbox 6.0.8
- Ubuntu 18.04 LTS (Bionic Beaver)
- Docker version 18.09.5, build e8ff056
- docker-compose version 1.24.0, build 0aa59064
構成
- app
- app.js
- docker
- docker-compose.yml
- nodejs
- Dockerfile
- nginx
- Dockerfile
- default.conf
- upstream.conf
例題のgithubページだと、以下だけなので、だいぶん冗長。
- app.js
- nginx.patch.conf
ソース
docker/docker-compose.yml
version: '3'
services:
nodejs:
build: ./nodejs
volumes:
- ../app:/app/app
command: [npm,run,run]
nginx:
build: ./nginx
ports:
- 80:80
node.jsのコンテナ作成時に、必要なモジュールのインストールを行う。
その後、package.jsonに実行したいコマンドをscriptに登録している。
docker/nodejs/Dockerfile
FROM node:12.5.0
WORKDIR /app
RUN npm init -y
RUN yarn add forever
RUN sed -i -e "s/\(\"scripts\": {\)/\1\n \"run\": \"forever start app\/app.js 8081 \&\& forever start app\/app.js 8082 \&\& forever start app\/app.js 8083 \&\& forever start app\/app.js 8084 \&\& forever list \&\& forever --fifo logs 0 \",/g" /app/package.json
ここでnpm run runで実行されるスクリプトは以下。
foreverだけだと、実行した後コンテナが終わってしまう。
コンテナを継続するためにログを出している。forever --fifo logs 0
forever start app/app.js 8081
forever start app/app.js 8082
forever start app/app.js 8083
forever start app/app.js 8084
forever list
forever --fifo logs 0
nginxはコンテナに設定ファイルを読み込むようにする。
docker/nginx/Dockerfile
FROM nginx
COPY default.conf /etc/nginx/conf.d/default.conf
COPY upstream.conf /etc/nginx/conf.d/upstream.conf
docker/nginx/default.conf
server {
listen 80;
location / {
proxy_pass http://nodejs_design_patterns_app;
}
}
サンプルでは127.0.0.1を指しているところを、コンテナの名前(nodejs)に置き換えている。
docker/nginx/upstream.conf
upstream nodejs_design_patterns_app {
server nodejs:8081;
server nodejs:8082;
server nodejs:8083;
server nodejs:8084;
}
app.jsは特に例題から変更なし。
app/app.js
"use strict";
const http = require('http');
const pid = process.pid;
http.createServer((req, res) => {
// 1e7: 10の累乗を指数で指定*1
for (let i = 1e7; i > 0; i--) {}
console.log(`Handling request from ${pid}`);
res.end(`Hello from ${pid}\n`);
}).listen(process.env.PORT || process.argv[2] || 8080, () => {
console.log(`Started ${pid}`);
});
参考
Node.jsデザインパターン 第2版
サポートページ
DockerでApache Benchをサクッと実行する
node.js express foreverアプリをdockerコンテナ化する
実践編ーDockerを使ってnginxでリバースプロキシを立ててみる