概要
Angular6で「俺式 KOAN スタック」で Web アプリ構築するための個人的な備忘録記事。
概要については「こちら」を参照。
事前に「ほぼ全手順(1)」が完了していることが前提。
今回の内容は「Web アプリの daemon(デーモン)化」「環境変数を操作し、アプリ実行モードによって色んな設定値を呼び分けられるようにする」
Web アプリの daemon(デーモン)化
現状のままだと、アプリ起動コマンド実行後は、以下のような状態になる。
...
> demo-app@0.0.0 serve:node /path/to/webapp/demo-app
> node dist/web-server.js
======================================================================
MEAN stack Template App. アプリ名をここに表示
======================================================================
=========================================================== ver.0.0.0
App is listening on http://localhost:3000
この状態だと、「コマンド実行後、裏でアプリを動かしっぱなしにする」ということが出来ない。
なので、アプリを daemon(デーモン)化して、バックグラウンドでも起動したアプリが止まらないようにする。
1.daemon 化モジュール "forever" をインストール
npm install forever
2.アプリ起動コマンドを追加
forever 実行するスクリプトを、以下のとおり追記。
(呼出コマンド、アプリ起動コマンド、起動済み一覧表示コマンド、停止コマンド)
{
"name": "demo-app",
"version": "0.0.0",
"scripts": {
"start": "npm run clean && npm run build && npm run serve:node",
"forever": "npm run clean && npm run build && npm run serve:forevr", // 追加
"list": "forever list", // 追加
"clean": "rm -rf dist",
"build": "npm run build:client && npm run build:server",
"build:client": "ng build",
"build:server": "tsc --project server --outDir dist --allowjs true",
"serve:node": "node dist/web-server.js",
"serve:forevr": "forever start dist/web-server.js", // 追加
"stop": "forever stop dist/web-server.js", // 追加
...
},
...
3.確認
起動確認
試しに実行してみる。
npm run forever
以下のようになれば、daemon 化成功。
...
> demo-app@0.0.0 serve:forevr /path/to/webapp/demo-app
> forever start dist/web-server.js
warn: --minUptime not set. Defaulting to: 1000ms
warn: --spinSleepTime not set. Your script will exit if it does not stay up for at least 1000ms
info: Forever processing file: dist/web-server.js # アプリ起動完了
my-mac:demo-app-dir user$ # コマンド完了後、返ってくる
これで、アプリ起動しても他のコマンド打てるし、ターミナル落としても起動アプリが勝手に止まったりしなくなる。
起動中のアプリを確認
npm run list
実行すると、以下のように、実行中のスクリプトやコマンド履歴、IDなどが出る。
> demo-app@0.0.0 list /path/to/webapp/demo-app
> forever list
info: Forever processes running
data: uid command script forever pid id logfile uptime
# 起動中のアプリ ▼
data: [0] BQIE /usr/local/bin/node dist/web-server.js 13168 13169 /Users/tommy/.forever/BQIE.log 0:0:9:43.442
停止確認
以下のコマンドで daemon 化されたアプリを停止できる。
npm run stop
もう一度 npm run list
で確認すると、以下のように起動中一覧からアプリが消える。
> demo-app@0.0.0 list /path/to/webapp/demo-app
> forever list
info: No forever processes running # 起動中のアプリが存在しない
環境変数を操作し、設定を呼び分けられるようにする
1.node-config を導入する
起動時に NODE_ENV (環境変数) を指定するだけで config ファイルを自動で呼び分けてくれる便利なモジュール、node-config をインストール。と、同時に、型定義ファイルもインストール。
npm install config @types/config
2.環境変数毎の設定ファイルを作成
node-config の仕様どおりに、ルートディレクトリ直下に config というディレクトリを用意して、環境変数に対応した設定ファイルを作る。
設定ファイルの形式は json などに対応しているが、今回はコメントも記載できて書きやすい yaml (ヤムル) ファイルで書く。
今回作成する環境値
- ローカル環境(daemon 化せずに node アプリ起動する環境)
- 開発環境 (daemon 化してアプリ起動するが、開発用)
- 本番環境 (daemon 化してアプリ起動し、本番で動かす用)
config ファイル作成:ローカル環境
---
# ローカルマシン環境用 設定値
mode: 'local'
description: 'local モードでアプリ起動'
port: 3000
config ファイル作成:開発環境
---
# 開発環境用 設定値
mode: 'development'
description: 'development モードでアプリ起動'
port: 3000
config ファイル作成:本番環境
---
# 開発環境用 設定値
mode: 'production'
description: 'production モードでアプリ起動'
port: 3000
3.web-server.ts を修正
node-config を使用して、web-server.ts を以下のとおり修正してみる。
- アプリ起動時に、設定ファイルからアプリのポート番号を設定する
- API 呼び出し時、環境変数を動的に返却するように設定してみる
...
import * as Koa from 'koa';
import * as koaStatic from 'koa-static';
import * as KoaRouter from 'koa-router';
import * as bodyParser from 'koa-bodyparser';
import * as config from 'config'; // 追加
import { join } from 'path';
const app = new Koa();
const PORT = process.env.PORT || config.get('port'); // 修正:3000 -> config のポート値を使用
const clientSrcPath = join(process.cwd(), 'dist/client');
...
const koaRouter = new KoaRouter();
koaRouter.get('/api/*', (ctx) => {
let response = 'API が呼ばれました'; // 追加
response += `process.env.NODE_ENV: ${process.env.NODE_ENV}`; // 追加
response += `設定ファイル: ${config}`; // 追加
ctx.status = 200;
ctx.body = response; // 修正
});
...
4.アプリ起動コマンドを修正
実行環境別にスクリプトを用意する。以下のとおりに追記・修正。
{
"name": "demo-app",
"version": "0.0.0",
"scripts": {
"local": "npm run clean && npm run build && npm run serve:local", // 修正: start -> local ローカル環境用
"start:dev": "npm run clean && npm run build && npm run serve:dev", // 修正: forever -> start:dev 開発環境用
"start:prod": "npm run clean && npm run build && npm run serve:prod", // 追加: 本番環境用
"list": "forever list",
"clean": "rm -rf dist",
"build": "npm run build:client && npm run build:server",
"build:client": "ng build",
"build:server": "tsc --project server --outDir dist --allowjs true",
"serve:local": "NODE_ENV=production node dist/web-server.js", // 修正: start -> local ローカル環境用
"serve:dev": "NODE_ENV=production forever start --uid demo-app-dev dist/web-server.js", // 修正: start -> local 開発環境用
"serve:prod": "NODE_ENV=production forever start --uid demo-app dist/web-server.js", // 追加: 本番環境用
"stop:dev": "forever stop demo-app-dev", // 修正: UID を指定して 開発環境 アプリ停止
"stop:prod": "forever stop demo-app", // 追加: UID を指定して 本番環境 アプリ停止
...
},
...
「NODE_ENV=xxx」を指定しながらアプリ起動することで、対応する config ファイルが自動で呼び出され、同時に 環境変数 process.env.NODE_ENV
に環境値が格納される。
また、 forever start にオプション --uid
を指定することで、起動済みアプリ一覧表示時に何を起動したかわかるようになる。アプリ停止も UID で行える。
5.確認
ローカル環境モードで起動してみる
アプリ起動
npm run local
ブラウザから API アクセス
Web ブラウザから http://localhost:3000/api/aaa
にアクセスすると以下のように出る

アプリ停止
Ctrl
+C
で停止
開発環境モードで起動してみる
アプリ起動
npm run start:dev
起動アプリ一覧表示
> demo-app@0.0.0 list /path/to/webapp/demo-app
> forever list
info: Forever processes running
data: uid command script forever pid id logfile uptime
# 開発環境用アプリ ▼
data: [0] demo-app-dev /usr/local/bin/node dist/web-server.js 14536 14537 /Users/tommy/.forever/demo-app-dev.log 0:0:0:46.339
UID の部分に demo-app-dev
と表示される
ブラウザから API アクセス
Web ブラウザから http://localhost:3000/api/aaa
にアクセスすると以下のように出る

アプリ停止
npm run stop:dev
本番環境モードで起動してみる
アプリ起動
npm run start:prod
起動アプリ一覧表示
> demo-app@0.0.0 list /path/to/webapp/demo-app
> forever list
info: Forever processes running
data: uid command script forever pid id logfile uptime
# 本番環境用アプリ ▼
data: [0] demo-app /usr/local/bin/node dist/web-server.js 14571 14572 /Users/tommy/.forever/demo-app.log 0:0:0:4.12
UID の部分に demo-app
と表示される
ブラウザから API アクセス
Web ブラウザから http://localhost:3000/api/aaa
にアクセスすると以下のように出る

アプリ停止
npm run prod
結果
同じソースコードでも、起動コマンドを変えることで、環境変数や設定値を、動的に変えられることが確認できた。
これによって、例えば、外部 API のアクセス先やログの出力先などを設定ファイル別に書くことで、いちいち NODE_ENV 変数を呼び出して if 文などで処理を分岐させるようなソースコードを書かなくてすむ。
この後やること
画面のボタンから複数の API を呼べるように通信部を作り込む。