Giter VIP home page Giter VIP logo

pm2's Introduction

PM2

PM2 is a process manager for Node.JS application with a built-in load balancer.

Main features

  • Advanced process management
  • Built-in load balancer (Node.JS)
  • 0s downtime reload (Node.JS)
  • JSON application declaration
  • Log management
  • Programmatic interface with embeddable capabilities
  • Provisioning and Deployment system
  • Application resource monitoring (RAM, CPU)
  • Application daemonization
  • Assisted startup script creation (SystemV/SystemD/Upstart)
  • Automatically restart process based on memory limit
  • Automatically stop unstable process (at launch)
  • Automatically restart process on file change

Full test suit with more than 300 tests: (https://travis-ci.org/Unitech/PM2)

We recommend the Node.js version v0.11.13 for better cluster management

Compatible with CoffeeScript. Works on Linux & MacOS. Windows upcoming.

NPM version Donate

NPM

Build Status

Master: Build Status

Development: Build Status

Monitoring dashboard

Dashboard

We are developing a radically innovative product that will offer you to monitor and augment your Node.JS applications, as you never saw before. Here are some links:

Thanks in advance and we hope that you like PM2!


Table of contents

Quick start

Features

Deployment - ecosystem.json

Using PM2 programmatically (via API)

Specific

Knowledge

More


Quick start

## Installation

One more time we recommend Node.JS 0.11.13 (manage Node.JS versions easily with https://github.com/creationix/nvm)

The latest PM2 stable version is installable via NPM:

$ npm install pm2@latest -g

If the above fails use:

$ npm install git://github.com/Unitech/pm2#master -g
## Usage

Hello world:

$ pm2 start app.js
## Raw Examples
$ pm2 start app.js --name my-api # Name process

$ pm2 start app.js -i max        # Will start maximum processes with LB depending on available CPUs

# Listing

$ pm2 list               # Display all processes status
$ pm2 jlist              # Print process list in raw JSON
$ pm2 prettylist         # Print process list in beautified JSON

$ pm2 describe 0         # Display all informations about a specific process

$ pm2 monit              # Monitor all processes

# Logs

$ pm2 logs               # Display all processes logs in streaming
$ pm2 ilogs              # Advanced termcaps interface to display logs
$ pm2 flush              # Empty all log file
$ pm2 reloadLogs         # Reload all logs

# Actions

$ pm2 stop all           # Stop all processes
$ pm2 restart all        # Restart all processes

$ pm2 reload all         # Will 0s downtime reload (for NETWORKED apps)
$ pm2 gracefulReload all # Send exit message then reload (for networked apps)

$ pm2 stop 0             # Stop specific process id
$ pm2 restart 0          # Restart specific process id

$ pm2 delete 0           # Will remove process from pm2 list
$ pm2 delete all         # Will remove all processes from pm2 list

# Misc

$ pm2 reset <process>    # Reset meta data (restarted time...)
$ pm2 updatePM2          # Update in memory pm2
$ pm2 ping               # Ensure pm2 daemon has been launched
$ pm2 sendSignal SIGUSR2 my-app # Send system signal to script
$ pm2 start app.js --no-daemon
$ pm2 start app.js -i max  # Will start maximum processes depending on available CPUs

$ pm2 start app.js -i 3    # Will start 3 processes

$ pm2 start app.js -i max -- -a 23  # Pass arguments after -- to app.js

$ pm2 start app.js -x            # Start app.js in fork mode instead of cluster
$ pm2 start app.js -x -- -a 23   # Start app.js in fork mode and pass arguments (-a 23)

$ pm2 start app.js --log-date-format "YYYY-MM-DD HH:mm Z"    # Log will be prefixed with custom time format

$ pm2 start app.js --name serverone # Start a process an name it as server one
                                    # you can now stop the process by doing
                                    # pm2 stop serverone

$ pm2 start app.json                # Start processes with options declared in app.json
                                    # Go to chapter Multi process JSON declaration for more

$ pm2 start app.js -i max -e err.log -o out.log  # Will start and generate a configuration file

$ pm2 start app.js --node-args="--debug=7001 --trace-deprecation" # --node-args command line option to pass options to node

$ pm2 --run-as-user foo start app.js  # Start app.js as user foo instead of root (pm2 must be running as root)

$ pm2 --run-as-user foo --run-as-group bar start app.js  # Start app.js as foo:bar instead of root:root (pm2 must be running as root)

For scripts in other languages:

$ pm2 start echo.coffee
$ pm2 start -x echo.php
$ pm2 start -x echo.py
$ pm2 start -x echo.sh
$ pm2 start -x echo.rb
$ pm2 start -x echo.pl

Languages other than javascript have to be run in fork mode.

## Options
Options:

    -h, --help                   output usage information
    -V, --version                output the version number
    -v --verbose                 verbose level
    -s --silent                  hide all messages
    -m --mini-list               display a compacted list without formatting
    -f --force                   force actions
    -n --name <name>             set a <name> for script
    -i --instances <number>      launch [number|'max'] (load balanced) instances (for networked app)
    -o --output <path>           specify out log file
    -e --error <path>            specify error log file
    -p --pid <pid>               specify pid file
    -x --execute-command         execute a program using fork system
    -u --user <username>         define user when generating startup script
    -c --cron <cron_pattern>     restart a running process based on a cron pattern
    -w --write                   write configuration in local folder
    --interpreter <interpreter>  the interpreter pm2 should use for executing app (bash, python...)
    --no-daemon                  run pm2 daemon in the foreground if it doesn't exist already
    --merge-logs                 merge logs
    --watch                      watch folder(s) for changes. When `true`, watching all folders from root. Can also be a string or an array of strings for paths to watch for changes.
    --node-args <node_args>      space-delimited arguments to pass to node in cluster mode - e.g. --node-args="--debug=7001 --trace-deprecation"
    --run-as-user <run_as_user>    The user or uid to run a managed process as
    --run-as-group <run_as_group>  The group or gid to run a managed process as
## How to update PM2

Install the latest pm2 version :

$ npm install pm2@latest -g

Then update the in-memory PM2 :

$ pm2 updatePM2
## Transitional state of apps (important)

PM2 is a process manager. PM2 can start, stop, restart and delete processes.

Start a process:

$ pm2 start app.js --name "my-api"
$ pm2 start web.js --name "web-interface"

Now let's say I need to stop the web-interface:

$ pm2 stop web-interface

As you can see the process hasn't disappeared. It's still there but in stopped status.

To restart it just do:

$ pm2 restart web-interface

Now I want to delete the app from the PM2 process list. To do so:

$ pm2 delete web-interface
## Process listing

Monit

To list all running processes:

$ pm2 list
# Or
$ pm2 [list|ls|l|status]

To get more details about a specific process:

$ pm2 describe 0
## Automatic restart process based on memory

Value passed is in megaoctets. Internally it uses the V8 flag --max-old-space-size=MEM to make a process exit when memory exceed a certain amount of RAM used.

CLI:

$ pm2 start big-array.js --max-memory-restart 20

JSON:

{
  "name" : "max_mem",
  "script" : "big-array.js",
  "max_memory_restart" : "20"
}
## Monitoring CPU/Memory usage

Monit

Monitor all processes launched:

$ pm2 monit
## Logs management

Monit

Displaying logs of specified process or all processes in realtime:

$ pm2 logs
$ pm2 logs big-api
$ pm2 flush # Clear all the logs

Advanced log interface

Navigate between processes logs in realtime with an ergonomic interface:

$ pm2 ilogs

Reloading all logs (SIGUSR2/Logrotate)

To reload all logs, you can send SIGUSR2 to the PM2 process.

You can also reload all logs via the command line with:

$ pm2 reloadLogs

Options

--merge-logs : merge logs from different instances but keep error and out separated
--log-date-format <format>: prefix logs with formated timestamp (http://momentjs.com/docs/#/parsing/string-format/)
## Clustering

Launch max instances (max depending on the number of CPUs available) and set the load balancer to balance queries among process:

$ pm2 start app.js --name "API" -i max

If your app is well-designed (stateless) you'll be able to process many more queries.

Important concepts to make a Node.js app stateless:

## Reloading without downtime

As opposed to restart, which kills and restarts the process, reload achieves a 0-second-downtime reload.

Warning This feature only works for apps in cluster mode (the default mode), that uses HTTP/HTTPS/Socket connections.

To reload an app:

$ pm2 reload api

If the reload system hasn't managed to reload gracefully, a timeout will simply kill the process and will restart it.

Sometimes you can experience a very long reload, or a reload that doesn't work (fallback to restart).

It means that your app still has open connections on exit.

To work around this problem you have to use the graceful reload. Graceful reload is a mechanism that will send a shutdown message to your process before reloading it. You can control the time that the app has to shutdown via the PM2_GRACEFUL_TIMEOUT environment variable.

Example:

process.on('message', function(msg) {
  if (msg == 'shutdown') {
    // Your process is going to be reloaded
    // You have to close all database/socket.io/* connections

    console.log('Closing all connections...');

    // You will have 4000ms to close all connections before
    // the reload mechanism will try to do its job

    setTimeout(function() {
      console.log('Finished closing connections');
      // This timeout means that all connections have been closed
      // Now we can exit to let the reload mechanism do its job
      process.exit(0);
    }, 1500);
  }
});

Then use the command:

$ pm2 gracefulReload [all|name]

When PM2 starts a new process to replace an old one, it will wait for the new process to begin listening to a connection before sending the shutdown message to the old one. If a script does not need to listen to a connection, it can manually tell PM2 that the process has started up by calling process.send('online').

## Startup script

PM2 has the amazing ability to generate startup scripts and configure them. PM2 is also smart enough to save all your process list and to bring back all your processes on restart.

$ pm2 startup [ubuntu|centos|gentoo|systemd]

Once you have started the apps and want to keep them on server reboot do:

$ pm2 save

Warning It's tricky to make this feature work generically, so once PM2 has setup your startup script, reboot your server to make sure that PM2 has launched your apps!

Three types of startup scripts are available:

  • SystemV init script (with the option ubuntu or centos)
  • OpenRC init script (with the option gentoo)
  • SystemD init script (with the systemd option)

The startup options are using:

  • ubuntu will use updaterc.d and the script lib/scripts/pm2-init.sh
  • centos will use chkconfig and the script lib/scripts/pm2-init-centos.sh
  • gentoo will use rc-update and the script lib/scripts/pm2
  • systemd will use systemctl and the script lib/scripts/pm2.service

User permissions

Let's say you want the startup script to be executed under another user.

Just use the -u <username> option !

$ pm2 startup ubuntu -u www

Related commands

Dump all processes status and environment managed by PM2:

$ pm2 dump

It populates the file ~/.pm2/dump.pm2 by default.

To bring back the latest dump:

$ pm2 resurrect
## Watch & Restart

PM2 can automatically restart your app when a file changes in the current directory or its subdirectories:

$ pm2 start app.js --watch

If --watch is enabled, stopping it won't stop watching:

  • pm2 stop 0 'll not stop watching
  • pm2 stop --watch 0 'll stop watching

Restart toggle the watch parameter when triggered.

To watch specifics paths, please use a JSON app declaration, watch can take a string or an array of paths. Default is true:

{
  "watch": ["server", "client"],
  "ignoreWatch" : ["node_modules", "client/img"]
}
## JSON app declaration

You can define parameters for your apps in processes.json:

{
  "apps" : [{
    "name"        : "echo",
    "script"      : "examples/args.js",
    "args"        : "['--toto=heya coco', '-d', '1']",
    "log_date_format"  : "YYYY-MM-DD HH:mm Z",
    "ignoreWatch" : ["[\\/\\\\]\\./", "node_modules"],
    "watch"       : "true",
    "node_args"   : "--harmony",
    "cwd"         : "/this/is/a/path/to/start/script",
    "env": {
        "NODE_ENV": "production",
        "AWESOME_SERVICE_API_TOKEN": "xxx"
    }
  },{
    "name"       : "api",
    "script"     : "./examples/child.js",
    "instances"  : "4",
    "log_date_format"  : "YYYY-MM-DD",
    "error_file" : "./examples/child-err.log",
    "out_file"   : "./examples/child-out.log",
    "pid_file"   : "./examples/child.pid",
    "exec_mode"  : "cluster_mode",
    "port"       : 9005
  },{
    "name"       : "auto-kill",
    "script"     : "./examples/killfast.js",
    "min_uptime" : "100",
    "exec_mode"  : "fork_mode",
  }]
}

Then run:

$ pm2 start processes.json
$ pm2 stop processes.json
$ pm2 delete processes.json
$ pm2 restart processes.json

A few notes about JSON app declarations:

  • All command line options passed when using the JSON app declaration will be dropped i.e.
$ cat node-app-1.json

{
  "name" : "node-app-1",
  "script" : "app.js",
  "cwd" : "/srv/node-app-1/current"
}

$ pm2 --run-as-user app start node-app-1.json

$ ps aux | grep node-app
root 14735 5.8 1.1 752476 83932 ? Sl 00:08 0:00 pm2: node-app-1  <-- owned by the default user (root), not app
  • JSON app declarations are additive. Continuing from above:
$ pm2 start node-app-2.json
$ ps aux | grep node-app
root  14735  5.8  1.1  752476  83932 ? Sl 00:08 0:00 pm2: node-app-1
root  24271  0.0  0.3  696428  24208 ? Sl 17:36 0:00 pm2: node-app-2

Note that if you execute pm2 start node-app-2 again, it will spawn an additional instance node-app-2.

  • cwd: your JSON declaration does not need to reside with your script. If you wish to maintain the JSON(s) in a location other than your script (say, /etc/pm2/conf.d/node-app.json) you will need to use the cwd feature. (Note, this is especially helpful for capistrano style directory structures that use symlinks.) Files can be either relative to the cwd directory, or absolute (example below.)

  • The following are valid options for JSON app declarations:

[{
  "name"             : "node-app",
  "cwd"              : "/srv/node-app/current",
  "args"             : "['--toto=heya coco', '-d', '1']",
  "script"           : "bin/app.js",
  "node_args"        : "--harmony",
  "log_date_format"  : "YYYY-MM-DD HH:mm Z",
  "error_file"       : "/var/log/node-app/node-app.stderr.log",
  "out_file"         : "log/node-app.stdout.log",
  "pid_file"         : "pids/node-geo-api.pid",
  "run_as_user"      : "app",
  "run_as_group"     : "www-data",
  "instances"        : "6", //or 'max'
  "min_uptime"       : "200", // milliseconds, defaults to 1000
  "max_restarts"     : "10", // defaults to 15
  "cron_restart"     : "1 0 * * *",
  "watch"            : "false",
  "ignoreWatch"      : ["[\\/\\\\]\\./", "node_modules"],
  "merge_logs"       : "true",
  "exec_interpreter" : "node",
  "exec_mode"        : "cluster_mode",
  "env": {
    "NODE_ENV": "production",
    "AWESOME_SERVICE_API_TOKEN": "xxx"
  }
}]
# Deployment (PM2 >= 0.9.0)

PM2 embed a simple and powerful deployment system with revision tracing. It's based on https://github.com/visionmedia/deploy

A step-by-step tutorial is available here : Deploy and Iterate faster with PM2 deploy

Getting started with deployment

Please read the Considerations to use PM2 deploy

1- Generate a sample ecosystem.json file that list processes and deployment environment

$ pm2 ecosystem

In the current folder a ecosystem.json file will be created. It contains this:

{
  "apps" : [{
    "name"      : "API",
    "script"    : "app.js",
    "env": {
      "COMMON_VARIABLE": "true"
    },
    "env_production" : {
      "NODE_ENV": "production"
    }
  },{
    "name"      : "WEB",
    "script"    : "web.js"
  }],
  "deploy" : {
    "production" : {
      "user" : "node",
      "host" : "212.83.163.1",
      "ref"  : "origin/master",
      "repo" : "[email protected]:repo.git",
      "path" : "/var/www/production",
      "post-deploy" : "pm2 startOrRestart ecosystem.json --env production"
    },
    "dev" : {
      "user" : "node",
      "host" : "212.83.163.1",
      "ref"  : "origin/master",
      "repo" : "[email protected]:repo.git",
      "path" : "/var/www/development",
      "post-deploy" : "pm2 startOrRestart ecosystem.json --env dev"
    }
  }
}

Edit the file according to your needs.

2- Be sure that you have the public ssh key on your local machine

$ ssh-keygen -t rsa
$ ssh-copy-id [email protected]

3- Now initialize the remote folder with:

$ pm2 deploy <configuration_file> <environment> setup

E.g:

$ pm2 deploy ecosystem.json production setup

This command will create all the folders on your remote server.

4- Deploy your code

$ pm2 deploy ecosystem.json production

Now your code will be populated, installed and started with PM2

## Deployment options
$ pm2 deploy <configuration_file> <environment> <command>

  Commands:
    setup                run remote setup commands
    update               update deploy to the latest release
    revert [n]           revert to [n]th last deployment or 1
    curr[ent]            output current release commit
    prev[ious]           output previous release commit
    exec|run <cmd>       execute the given <cmd>
    list                 list previous deploy commits
    [ref]                deploy to [ref], the "ref" setting, or latest tag
## Considerations
  • You might want to commit your node_modules folder (#622) or add the npm install command to the post-deploy section: "post-deploy" : "npm install && pm2 startOrRestart ecosystem.json --env production"
  • You can declare specific environment variable depending on the environment you want to deploy the code to. For instance to declare variables for the production environment, just add "env_production": {} and declare that variables.
  • PM2 will look by default to ecosystem.json. So you can skip the <configuration_file> options if it's the case
  • You can embed the "apps" & "deploy" section in the package.json
  • It deploys your code via ssh, you don't need any dependencies
  • Process are initialized / started automatically depending on application name in ecosystem.json
  • PM2-deploy repoitory is there: pm2-deploy
## Contributing

The module is https://github.com/Unitech/pm2-deploy Feel free to PR for any changes or fix.

# Using PM2 programmatically

PM2 can be used programmatically, meaning that you can embed a process manager directly in your code, spawn processes, keep them alive even if the main script is exited.

Check out this article for more informations.

Simple example

This will require pm2, launch test.js, list processes then exit the script. You will notice that after exiting this script you will be able to see test.js process with pm2 list

$ npm install pm2 --save
var pm2 = require('pm2');

// Connect or launch PM2
pm2.connect(function(err) {

  // Start a script on the current folder
  pm2.start('test.js', { name: 'test' }, function(err, proc) {
    if (err) throw new Error('err');

    // Get all processes running
    pm2.list(function(err, process_list) {
      console.log(process_list);

      // Disconnect to PM2
      pm2.disconnect(function() { process.exit(0) });
    });
  });
})
## Programmatic API
Method name API
Connect/Launch pm2.connect(fn(err){})
Disconnect pm2.disconnect(fn(err, proc){})

Consideration with .connect: the .connect method connect to the local PM2, but if PM2 is not up, it will launch it and will put in in background as you launched it via CLI.

<tr>
  <td><b>Reload</b></td>
  <td>pm2.reload(proc_name|all, fn(err, proc){})</td>
</tr>
  <tr>
  <td><b>Graceful Reload</b></td>
  <td>pm2.gracefulReload(proc_name|all, fn(err, proc){})</td>
</tr>
Method name API
Start pm2.start(script_path|json_path, options, fn(err, proc){})
Options nodeArgs(arr), scriptArgs(arr), name(str), instances(int), error(str), output(str), pid(int), cron(str), mergeLogs(bool), watch(bool), runAsUser(int), runAsGroup(int), executeCommand(bool), interpreter(str), write(bool)
Restart pm2.restart(proc_name|proc_id|all, fn(err, proc){})
Stop pm2.stop(proc_name|proc_id|all, fn(err, proc){})
Delete pm2.delete(proc_name|proc_id|all, fn(err, proc){})
Method name API
List pm2.list(fn(err, list){})
Describe process pm2.describe(proc_name|proc_id, fn(err, list){})
Dump (save) pm2.dump(fn(err, ret){})
Flush logs pm2.flush(fn(err, ret){})
Reload logs pm2.reloadLogs(fn(err, ret){})
Send signal pm2.sendSignalToProcessName(signal,proc,fn(err, ret){})
Generate start script pm2.startup(platform, fn(err, ret){})
Kill PM2 pm2.killDaemon(fn(err, ret){})
# Special features

Launching PM2 without daemonizing itself:

$ pm2 start app.js --no-daemon

Sending a system signal to a process:

$ pm2 sendSignal SIGUSR2 my-app
## Configuration file

You can specify the following options by editing the file ~/.pm2/custom_options.sh:

PM2_RPC_PORT
PM2_PUB_PORT
PM2_BIND_ADDR
PM2_API_PORT
PM2_GRACEFUL_TIMEOUT
PM2_MODIFY_REQUIRE
$ pm2 web
## Enabling Harmony ES6

The --node-args option permit to launch script with V8 flags, so to enable harmony for a process just do this:

$ pm2 start my_app.js --node-args="--harmony"

And with JSON declaration:

[{
  "name" : "ES6",
  "script" : "es6.js",
  "node_args" : "--harmony"
}]
## CoffeeScript
$ pm2 start my_app.coffee

That's all!

## Stateless apps

We recommend (and you must) write stateless NodeJS apps. Apps that don't retain any form of local variables or local instances or whatever local. Every data, states, websocket session, session data, must be shared via any kind of database.

We recommend using Redis for sharing session data, websocket.

We recommend following the 12 factor convention : http://12factor.net/

## Setup pm2 on a server

How To Use pm2 to Setup a Node.js Production Environment On An Ubuntu VPS

## Log and PID files

By default, logs (error and output), pid files, dumps, and PM2 logs are located in ~/.pm2/:

.pm2/
├── dump.pm2
├── custom_options.sh
├── pm2.log
├── pm2.pid
├── logs
└── pids
## Execute any script: What is fork mode?

The default mode of PM2 consists of wrapping the code of your node application into the Node Cluster module. It's called the cluster mode.

There is also a more classical way to execute your app, like node-forever does, called the fork mode.

In fork mode almost all options are the same as the cluster mode. But there is no reload or gracefulReload command.

By using the fork mode you will lose core features of pm2 like the automatic clusterization of your code over all CPUs available and the 0s reload.

So use it if you only need a forever-like behaviour.

Here is how to start your app within a fork:

$ pm2 start app.js -x   # Will start your app.js in fork mode
$ pm2 list              # You will see that on the row "mode" it's written "fork"

You can also exec scripts written in other languages:

$ pm2 start my-bash-script.sh -x --interpreter bash

$ pm2 start my-python-script.py -x --interpreter python

The interpreter is deduced from the file extension from the following list.

## JSON app configuration via pipe from stdout

Pull-requests:

#!/bin/bash

read -d '' my_json <<_EOF_
[{
    "name"       : "app1",
    "script"     : "/home/projects/pm2_nodetest/app.js",
    "instances"  : "4",
    "error_file" : "./logz/child-err.log",
    "out_file"   : "./logz/child-out.log",
    "pid_file"   : "./logz/child.pid",
    "exec_mode"  : "cluster_mode",
    "port"       : 4200
}]
_EOF_

echo $my_json | pm2 start -
## Is my production server ready for PM2?

Just try the tests before using PM2 on your production server

$ git clone https://github.com/Unitech/pm2.git
$ cd pm2
$ npm install  # Or do NODE_ENV=development npm install if some packages are missing
$ npm test

If a test is broken please report us issues here Also make sure you have all dependencies needed. For Ubuntu:

$ sudo apt-get install build-essential
# nvm is a Node.js version manager - https://github.com/creationix/nvm
$ wget -qO- https://raw.github.com/creationix/nvm/master/install.sh | sh
$ nvm install v0.11.10
$ nvm use v0.11.10
$ nvm alias default v0.11.10
## Contributing/Development mode

To hack PM2, it's very simple:

$ pm2 kill   # kill the current pm2
$ git clone my_pm2_fork.git
$ cd pm2/
$ DEBUG=* PM2_DEBUG=true ./bin/pm2 --no-daemon

Each time you edit the code, be sure to kill and restart PM2 to make changes taking effect.

$ npm install git://github.com/Unitech/pm2#development -g
## Known bugs and workarounds

First, install the lastest PM2 version:

$ npm install -g pm2@latest

So if you feel that this problem is important for your use case, use the fork mode instead. By using the fork mode you will lose core features of PM2 like the automatic clusterization of your code over all CPUs available and the 0s reload.

$ pm2 start index.js -x  # start my app in fork mode

For more information about this, see issue #74.

Cannot read property 'getsockname' of undefined

When using the cluster mode (by default) you can't use ports from 0 to 1024. If you really need to exec in this range use the fork mode with the -x parameter. By using the fork mode you will lose core features of pm2 like the automatic clusterization of your code over all CPUs available and the 0s reload.

User tips from issues

## External resources and articles

Contributors

   195  tknew2
   184  Alexandre Strzelewicz
    20  Alex Kocharin
     8  soyuka
     6  sailxjx
     5  Bret Copeland
     4  AS
     4  Ville Walveranta
     4  achingbrain
     3  Ben Postlethwaite
     3  Evan You
     2  Frederico Silva
     2  Ivan Seidel
     2  MATSUU Takuto
     2  Oleg
     2  Willian
     2  Yani Iliev
     1  Almog Melamed
     1  Brent Burgoyne
     1  Daniel Pihlstrom
     1  Ed Hubbell
     1  Eugene Lucash
     1  Gil Pedersen
     1  Hao-kang Den
     1  John Hurliman
     1  Jose V. Trigueros
     1  Josh Skidmore
     1  Juozas Valenčius
     1  Kevin Gao
     1  Loïc Mahieu
     1  Mark Evans
     1  Nathan Peck
     1  TruongSinh Tran-Nguyen
     1  Wes Mason
     1  Zihua Li
     1  perfectworks
     1  subeeshcbabu
     1  Michael Heuberger

Sponsors

Thanks to Devo.ps and Wiredcraft for their knowledge and expertise.

Bitdeli Badge

# License

Files in lib/ are made available under the terms of the GNU Affero General Public License (AGPL). pm2-interface is made under the terms of the Apache V2 license.

pm2's People

Contributors

unitech avatar soyuka avatar rlidwka avatar dandv avatar sailxjx avatar nmrugg avatar achingbrain avatar bretcope avatar vwal avatar bpostlethwaite avatar yyx990803 avatar meanwhilemedia avatar fredericosilva avatar gumpcha avatar joshperry avatar matsuu avatar binarykitchen avatar olegskl avatar stephanx avatar willianpts avatar yani- avatar alanhoff avatar a0viedo avatar radagaisus avatar brentropy avatar carsondarling avatar mansona avatar sciolist avatar edhubbell avatar elucash avatar

Watchers

James Cloos avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.