在生产环境部署Node.js应用(使用PM2)

| Comments

OS: Ubuntu-server 12.10

1. Install Node.js ( https://github.com/joyent/node/wiki/Installing-Node.js-via-package-manager )

1
2
3
4
sudo apt-get install software-properties-common
sudo add-apt-repository ppa:chris-lea/node.js
sudo apt-get update
sudo apt-get install nodejs

2. Install PM2 ( https://github.com/Unitech/pm2 )

1
2
$sudo su
#npm install pm2@latest -g

3. Create INIT script

1
#pm2 startup

The content of /etc/init.d/pm2-init.sh, I modified it to start my app

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
#!/bin/bash
# chkconfig: 2345 98 02
#
# description: PM2 next gen process manager for Node.js
# processname: pm2
#
### BEGIN INIT INFO
# Provides:          pm2
# Required-Start:
# Required-Stop:
# Default-Start:        2 3 4 5
# Default-Stop:         0 1 6
# Short-Description: PM2 init script
# Description: PM2 is the next gen process manager for Node.js
### END INIT INFO

NAME=pm2
PM2=/usr/lib/node_modules/pm2/bin/pm2
NODE=/usr/bin/nodejs
USER=www-data
APPHOME=/var/www/ali_product_database/public/api

export HOME="/var/www"

super() {
    cd $APPHOME && sudo -u $USER $*
}

start() {
    echo "Starting $NAME"
    super $NODE $PM2 start app.js -i max
    super $NODE $PM2 resurrect
}

stop() {
    super $NODE $PM2 dump
    super $NODE $PM2 delete all
    super $NODE $PM2 kill
}

restart() {
    echo "Restarting $NAME"
    stop
    start
}

reload() {
    echo "Reloading $NAME"
    super $NODE $PM2 reload all
}

status() {
    echo "Status for $NAME:"
    $NODE $PM2 list
    RETVAL=$?
}

case "$1" in
    start)
        start
        ;;
    stop)
        stop
        ;;
    status)
        status
        ;;
    restart)
        restart
        ;;
    reload)
        reload
        ;;
    \*)
        echo "Usage: {start|stop|status|restart|reload}"
        exit 1
        ;;
esac
exit $RETVAL

4. Try to start up App:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
#/etc/init.d/pm2-init.sh start
Starting pm2
PM2 Process launched
┌──────────┬────┬─────────┬──────┬────────┬──────┬───────────┬────────┬──────────┬──────────────────────────────────┐
│ App Name │ id │ mode    │ PID  │ status │ port │ Restarted │ Uptime │   memory │ err logs                         │
├──────────┼────┼─────────┼──────┼────────┼──────┼───────────┼────────┼──────────┼──────────────────────────────────┤
│ app      │ 0  │ cluster │ 6816 │ online │      │         0 │ 0s     │ 8.203 MB │ /var/www/.pm2/logs/app-err-0.log │
└──────────┴────┴─────────┴──────┴────────┴──────┴───────────┴────────┴──────────┴──────────────────────────────────┘
PM2 Resurrecting
Processing......

fs.js:427
  return binding.open(pathModule._makeLong(path), stringToFlags(flags), mode);
                 ^
Error: ENOENT, no such file or directory '/var/www/.pm2/dump.pm2'
    at Object.fs.openSync (fs.js:427:18)
    at Object.fs.readFileSync (fs.js:284:15)
    at Object.CLI.resurrect (/usr/lib/node_modules/pm2/lib/CLI.js:244:17)
    at Command.<anonymous> (/usr/lib/node_modules/pm2/bin/pm2:138:9)
    at Command.<anonymous> (/usr/lib/node_modules/pm2/node_modules/commander/index.js:249:8)
    at Command.EventEmitter.emit (events.js:98:17)
    at Command.parseArgs (/usr/lib/node_modules/pm2/node_modules/commander/index.js:477:12)
    at Command.parse (/usr/lib/node_modules/pm2/node_modules/commander/index.js:370:21)
    at process.<anonymous> (/usr/lib/node_modules/pm2/bin/pm2:306:13)
    at process.EventEmitter.emit (events.js:92:17)

5. So we need to have a dump folder, create it manually:

1
$ sudo -u www-data mkdir /var/www/.pm2/dump.pm2

6. Start App again, the error can be ignored.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
#/etc/init.d/pm2-init.sh stop
# /etc/init.d/pm2-init.sh start
Starting pm2
{ online: true, success: true, pid: 7632 }
PM2 Process launched
┌──────────┬────┬─────────┬──────┬────────┬──────┬───────────┬────────┬──────────┬──────────────────────────────────┐
│ App Name │ id │ mode    │ PID  │ status │ port │ Restarted │ Uptime │   memory │ err logs                         │
├──────────┼────┼─────────┼──────┼────────┼──────┼───────────┼────────┼──────────┼──────────────────────────────────┤
│ app      │ 0  │ cluster │ 7638 │ online │      │         0 │ 0s     │ 8.211 MB │ /var/www/.pm2/logs/app-err-0.log │
└──────────┴────┴─────────┴──────┴────────┴──────┴───────────┴────────┴──────────┴──────────────────────────────────┘
PM2 Resurrecting
Processing......

fs.js:476
  var r = binding.read(fd, buffer, offset, length, position);
                  ^
Error: EISDIR, illegal operation on a directory
    at Object.fs.readSync (fs.js:476:19)
    at Object.fs.readFileSync (fs.js:310:28)
    at Object.CLI.resurrect (/usr/lib/node_modules/pm2/lib/CLI.js:244:17)
    at Command.<anonymous> (/usr/lib/node_modules/pm2/bin/pm2:138:9)
    at Command.<anonymous> (/usr/lib/node_modules/pm2/node_modules/commander/index.js:249:8)
    at Command.EventEmitter.emit (events.js:98:17)
    at Command.parseArgs (/usr/lib/node_modules/pm2/node_modules/commander/index.js:477:12)
    at Command.parse (/usr/lib/node_modules/pm2/node_modules/commander/index.js:370:21)
    at process.<anonymous> (/usr/lib/node_modules/pm2/bin/pm2:306:13)
    at process.EventEmitter.emit (events.js:92:17)

7. Check App running status

1
2
3
4
5
6
7
8
9
10
11
$pm2 list
┌──────────┬────┬─────────┬──────┬────────┬──────┬───────────┬────────┬───────────┬──────────────────────────────────┐
│ App Name │ id │ mode    │ PID  │ status │ port │ Restarted │ Uptime │    memory │ err logs                         │
├──────────┼────┼─────────┼──────┼────────┼──────┼───────────┼────────┼───────────┼──────────────────────────────────┤
│ app      │ 0  │ cluster │ 7638 │ online │      │         0 │ 104s   │ 35.973 MB │ /var/www/.pm2/logs/app-err-0.log │
└──────────┴────┴─────────┴──────┴────────┴──────┴───────────┴────────┴───────────┴──────────────────────────────────┘
$pm2 monit
⌬ PM2 monitoring :

 ● app                                 [                              ] 0 %
[0] [cluster_mode]                     [||||||||||||||||||||||||||    ] 35.973 MB

Comments