Paris.js #53

Gérer ses serveurs

de développement et de tests avec PM2

@alexisjanvier

@marmelab

Advanced, production process manager for Node.js

http://pm2.keymetrics.io/

Un projet classique

  • une API d'administration (Koa)
  • une API public (Koa)
  • une interface d'administration (ng-admin)
  • une application public (React/Redux)

https://github.com/marmelab/javascript-boilerplate

Développement

- un serveur Node pour les deux API

- un webpack-dev-server pour l'administration

et l'application public 

TESTS

- un serveur Node pour les deux API

- un serveur de statics (http-server) pour l'administration

et l'application public 

Lancement ""à la mano""

$: ./node_modules/.bin/nodemon --watch api --watch config src/api/index.js 
$: ./node_modules/.bin/webpack-dev-server --content-base=build \
--devtool=cheap-module-inline-source-map --hot --inline --quiet --progress

webpack-dev-server

node (nodemon)

bof ...

makefile

webpack.PID:
	@./node_modules/.bin/webpack-dev-server \
		--content-base=build \
		--devtool=cheap-module-inline-source-map \
		--hot \
		--inline \
		--quiet \
		--progress \
		& echo "$$!" > webpack.PID

stop-frontend-dev: webpack.PID
	@kill `cat $<` && rm $<
	@echo "Webpack server stopped"

run-api-dev: server.PID
server.PID:
	@./node_modules/.bin/nodemon --watch api --watch config api/index.js \
        & echo "$$!" > server.PID
stop-api-dev: server.PID
	@kill `cat $<` && rm $<
	@echo "Node server stopped"

run-dev: run-frontend-dev run-api-dev
stop-dev: stop-frontend-dev stop-api-dev

AVEC PM2

// config/pm2-servers/dev.json
{
  "apps" : [{
    "name"       : "bpm_api-dev",
    "script"     : "./src/api/index.js",
    "watch"      : ["./src/api", "./src/isomorphic", "config"],
    "instances"   : 1,
    "autorestart" : true,
    "env": {
        "NODE_ENV": "development",
    }
  }, {
    "name"       : "bpm_frontend-dev",
    "script"     : "./node_modules/.bin/webpack-dev-server",
    "args"       : [
        "--content-base=build",
        "--devtool=cheap-module-inline-source-map",
        "--hot",
        "--inline",
        "--quiet",
        "--progress"
    ],
    "instances"   : 1,
    "autorestart" : true,
    "env": {
        "NODE_ENV": "development",
    }
  }]
}
# makefile

run-dev:
	@node_modules/.bin/pm2 start ./config/pm2_servers/dev.json
stop-dev:
	@node_modules/.bin/pm2 delete ./config/pm2_servers/dev.json

Et beaucoup d'autres features : restart, logs, monitoring, ...

Lancement des tests fonctionnels

// config/pm2-servers/test.json

{
  "apps" : [{
    "name"       : "bpm_api-test",
    "script"     : "./src/api/index.js",
    "exec_mode"  : "fork",
    "env": {
      "NODE_ENV": "test",
      "NODE_PORT": 3010
    }
  },
  {
    "name"       : "bpm_frontend-test",
    "script"     : "./node_modules/.bin/http-server",
    "args"       : ["./build", "-p 8081", "--silent"],
    "exec_mode"  : "fork",
    "env": {
        "NODE_ENV": "test",
        "NODE_PORT": 3020
    }
  }]
}
# Makefile

test-frontend-functional: reset-test-database
	NODE_ENV=test make load-fixtures
	@make build-test
	@node_modules/.bin/pm2 start ./config/pm2_servers/test.json
	@node_modules/.bin/nightwatch --config="./e2e/frontend/nightwatch.json"
	@node_modules/.bin/pm2 delete ./config/pm2_servers/test.json

... et une API pour utiliser pm2 directement dans les tests

import pm2 from 'pm2';

pm2.connect((err) => {
  if (err) {
    console.error(err);
    process.exit(2);
  }

  pm2.start({
    script    : 'app.js',         // Script to be run
    exec_mode : 'cluster',        // Allow your app to be clustered
    instances : 4,                // Optional: Scale your app by 4
    max_memory_restart : '100M'   // Optional: Restart your app if it reaches 100Mo
  },(err, apps) => {
    pm2.disconnect();
  });
});

global Vs project

# ~/.pm2
.
├── conf.js
├── dump.pm2
├── logs
│   ├── bpm-api-dev-error-0.log
│   ├── bpm-api-dev-out-0.log
│   ├── bpm-frontend-dev-error-1.log
│   └── bpm-frontend-dev-out-1.log
├── module_conf.json
├── pids
├── pm2.log
├── pm2.pid
├── pub.sock
├── rpc.sock
└── touch

2 directories, 12 files
$: PM2_HOME='.myProject' ./node_modules/.bin/pm2 start ./config/pm2_servers/test.json

MERCI

Gérer ses serveurs de développement et de test avec PM2

By Incaya

Gérer ses serveurs de développement et de test avec PM2

Le projet PM2 (Process Manager 2) cible plutôt le suivi des processus Node en production. Pour autant, c’est un outil vraiment pratique pour administrer ses serveurs de développement et de test, par exemple lorsque l'on doit démarrer et arrêter plusieurs serveurs pour des tests fonctionnels. En 5 min, je peux montrer comment j’ai intégré pm2 dans ma stack JavaScript quotidienne.

  • 2,163