Deploy SPA projects using pm2

Recently, the company has a back office project, based on the development of reactive dva ant, which has been running for half a year. Today I want to share the changes to deploy the production environment using node.js.

Installation dependency

Build an express deployer

1
2
$ npm install express-generator -g
$ express --view=ejs pm2-deploy-react-project
  • After the execution, you can see the following structure
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
- bin
- www
- dist
- index.html
- index.67ed8c8d.css
- index.3f75559e.js
- log
- combined.outerr.log
- error.log
- out.log
- node_modules
- view
- error.ejs
- app.js
- ecosystem.config.js
- package.json
- LICENSE
- README.md
  • Now we need to install a cross-domain npm package, (node.js cross-domain)
1
$ npm install http-proxy-middleware -save

Preview source

  • Package.json becomes as follows

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    {
    "name": "server-feller",
    "version": "1.0.0",
    "private": true,
    "scripts": {
    "start": "node ./bin/www"
    },
    "dependencies": {
    "cookie-parser": "~1.4.3",
    "debug": "~2.6.9",
    "ejs": "~2.5.7",
    "express": "~4.16.0",
    "http-errors": "~1.6.2",
    "http-proxy-middleware": "^0.19.0",
    "morgan": "~1.9.0"
    }
    }
  • App.js becomes as follows to see the proxy for four servers

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
80
'use strict';
var createError = require('http-errors');
var express = require('express');
var path = require('path');
var cookieParser = require('cookie-parser');
var logger = require('morgan');
var proxy = require('http-proxy-middleware');
var fs = require('fs');
var app = express();
// set all proxy
app.use('/sapi', proxy({
target: 'http://sapi2.haohaoce.com',
changeOrigin: true,
pathRewrite:{
'^/sapi' : '/',
}
}));
app.use('/upload', proxy({
target: 'http://img.hhztest.com/upload',
changeOrigin: true,
pathRewrite:{
'^/upload' : '/',
}
}));
app.use('/Video', proxy({
target: 'http://video.hhztest.com/Video',
changeOrigin: true,
pathRewrite:{
'^/Video' : '/',
}
}));
app.use('/jump/', proxy({
target: 'http://t.haohaoce.com',
changeOrigin: true,
pathRewrite:{
'^/jump' : '/',
}
}));
// view engine setup
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'ejs');
app.use(logger('dev'));
app.use(express.json());
app.use(express.urlencoded({ extended: false }));
app.use(cookieParser());
app.use(express.static(path.join(__dirname, 'dist')));
// all server change to *
app.all('*',function (req, res) {
res.writeHead(200, { "Content-Type": "text/html;charset=utf-8" });
const html = fs.readFileSync(path.resolve(__dirname, 'dist/index.html'), 'utf-8')
res.send(html)
})
// catch 404 and forward to error handler
app.use(function(req, res, next) {
next(createError(404));
});
// error handler
app.use(function(err, req, res, next) {
// set locals, only providing error in development
res.locals.message = err.message;
res.locals.error = req.app.get('env') === 'development' ? err : {};
// render the error page
res.status(err.status || 500);
res.render('error');
});
module.exports = app;

Perform pm2 initialization

1
$ pm2 init

See the following result

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
module.exports = {
apps : [{
name : 'fe_seller',
script : './bin/www',
output: './log/out.log',
error: './log/error.log',
log: './log/combined.outerr.log',
log_date_format : "YYYY-MM-DD HH:mm Z",
watch : true,
env: {
PORT: 3000,
NODE_ENV: 'development'
},
env_production : {
PORT: 80,
NODE_ENV: 'production'
}
}],
deploy : {
production : {
user : 'node',
host : '212.83.163.1',
ref : 'origin/master',
repo : 'git@github.com:repo.git',
path : '/var/www/production',
'post-deploy' : 'npm install && pm2 reload ecosystem.config.js --env production'
}
}
};

At this point, a node server deploying the spa project has been set up, you can see the entire shelf with the pm2 daemon output node log

To experience the production environment or to preview the project in the development environment, you can execute the following command:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
# git clone
git clone https://github.com/oksite/pm2-deploy-react-project.git
# pm2 install dependencies
npm install -g pm2
# install dependencies
npm insatll
# serve with hot reload at localhost:3000
pm2 start
# close pm2 server
pm2 stop
# deploy server
pm2 deploy
#pm2 监控
pm2 monit