Add clustering via pm2 for deployment, add security headers and logging
This commit is contained in:
Родитель
a40b79e643
Коммит
8817d0270d
3
.env
3
.env
|
@ -1 +1,2 @@
|
|||
PORT=8989
|
||||
PORT=8989
|
||||
BASEURI=http://localhost:8989
|
|
@ -0,0 +1 @@
|
|||
web: node start.js
|
Различия файлов скрыты, потому что одна или несколько строк слишком длинны
|
@ -29,7 +29,7 @@
|
|||
<link rel="stylesheet" type="text/css" href="css/vendor/all-skins.min.css">
|
||||
<link rel="stylesheet" type="text/css" href="css/style.css">
|
||||
|
||||
<script src="//c.shpg.org/352/sp.js"></script>
|
||||
<script src="https://c.shpg.org/352/sp.js"></script>
|
||||
<!-- Google Analytics -->
|
||||
<script>
|
||||
(function () {
|
||||
|
@ -182,7 +182,7 @@
|
|||
<option value="Country">Country</option>
|
||||
</select>
|
||||
</form>
|
||||
|
||||
|
||||
<form class="filter-dropdown" id="Age" style="display:none;">
|
||||
<label for="filter" style="padding-top:5px">Select a filter: </label>
|
||||
<select class="custom-select">
|
||||
|
@ -231,7 +231,7 @@
|
|||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Charts and tables -->
|
||||
<!-- Charts and tables -->
|
||||
<div class="row">
|
||||
<div class="col-sm-12 results">
|
||||
<ul class="nav nav-tabs" id="myTab" role="tablist">
|
||||
|
@ -429,7 +429,7 @@
|
|||
|
||||
</div>
|
||||
<!-- ./wrapper -->
|
||||
|
||||
|
||||
<script>window.jQuery || document.write('<script src="js/vendor/jquery.min.js"><\/script>')</script>
|
||||
<script src="js/vendor/bootstrap.min.js"></script>
|
||||
<script src="js/vendor/adminlte.min.js"></script>
|
||||
|
|
Различия файлов скрыты, потому что одна или несколько строк слишком длинны
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
|
@ -4,7 +4,9 @@
|
|||
"description": "Visualizing data from Mozilla's Facebook survey",
|
||||
"main": "dist/index.html",
|
||||
"scripts": {
|
||||
"test": "echo \"Error: no test specified\" && exit 1"
|
||||
"test": "echo \"Error: no test specified\" && exit 1",
|
||||
"heroku-prebuild": "npm install pm2 -g",
|
||||
"heroku-postbuild": "gulp build"
|
||||
},
|
||||
"author": "Vojtech Sedlak",
|
||||
"devDependencies": {
|
||||
|
@ -28,7 +30,10 @@
|
|||
"d3": "^5.1.0",
|
||||
"express": "^4.16.3",
|
||||
"habitat": "^3.1.2",
|
||||
"jquery": "^3.3.1"
|
||||
"helmet": "^3.12.0",
|
||||
"jquery": "^3.3.1",
|
||||
"morgan": "^1.9.0",
|
||||
"pm2": "^2.10.3"
|
||||
},
|
||||
"license": "MIT"
|
||||
}
|
||||
|
|
41
server.js
41
server.js
|
@ -1,9 +1,50 @@
|
|||
const express = require('express');
|
||||
const app = express();
|
||||
const habitat = require('habitat');
|
||||
const morgan = require('morgan');
|
||||
const helmet = require('helmet');
|
||||
|
||||
habitat.load('.env');
|
||||
|
||||
app.use(morgan('combined'));
|
||||
|
||||
app.use(helmet({
|
||||
dnsPrefetchControl: {
|
||||
allow: false
|
||||
},
|
||||
frameguard: {
|
||||
action: 'deny'
|
||||
},
|
||||
hidePoweredBy: true,
|
||||
hsts: {
|
||||
maxAge: 31560000,
|
||||
includeSubDomains: true,
|
||||
preload: true
|
||||
},
|
||||
ieNoOpen: true,
|
||||
noSniff: true,
|
||||
xssFilter: true,
|
||||
contentSecurityPolicy: {
|
||||
directives: {
|
||||
defaultSrc: ['\'none\''],
|
||||
scriptSrc: [
|
||||
'\'self\'',
|
||||
'\'unsafe-inline\'',
|
||||
'\'unsafe-eval\'',
|
||||
'*.shpg.org',
|
||||
'https://www.google-analytics.com'
|
||||
],
|
||||
connectSrc: ['\'self\''],
|
||||
baseUri: ['\'self\''],
|
||||
styleSrc: ['\'self\'', '\'unsafe-inline\'', 'https://use.fontawesome.com'],
|
||||
fontSrc: ['\'self\'', 'https://use.fontawesome.com'],
|
||||
imgSrc: ['\'self\'', 'data:', '*.shpg.org'],
|
||||
objectSrc: ['\'self\''],
|
||||
sandbox: ['allow-scripts', 'allow-same-origin']
|
||||
}
|
||||
}
|
||||
}));
|
||||
|
||||
app.use(express.static(__dirname + '/dist'));
|
||||
|
||||
app.get('/', (req, res) => {
|
||||
|
|
|
@ -29,7 +29,7 @@
|
|||
<link rel="stylesheet" type="text/css" href="css/vendor/all-skins.min.css">
|
||||
<link rel="stylesheet" type="text/css" href="css/style.css">
|
||||
|
||||
<script src="//c.shpg.org/352/sp.js"></script>
|
||||
<script src="https://c.shpg.org/352/sp.js"></script>
|
||||
<!-- Google Analytics -->
|
||||
<script>
|
||||
(function () {
|
||||
|
@ -182,7 +182,7 @@
|
|||
<option value="Country">Country</option>
|
||||
</select>
|
||||
</form>
|
||||
|
||||
|
||||
<form class="filter-dropdown" id="Age" style="display:none;">
|
||||
<label for="filter" style="padding-top:5px">Select a filter: </label>
|
||||
<select class="custom-select">
|
||||
|
@ -231,7 +231,7 @@
|
|||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Charts and tables -->
|
||||
<!-- Charts and tables -->
|
||||
<div class="row">
|
||||
<div class="col-sm-12 results">
|
||||
<ul class="nav nav-tabs" id="myTab" role="tablist">
|
||||
|
@ -429,7 +429,7 @@
|
|||
|
||||
</div>
|
||||
<!-- ./wrapper -->
|
||||
|
||||
|
||||
<script>window.jQuery || document.write('<script src="js/vendor/jquery.min.js"><\/script>')</script>
|
||||
<script src="js/vendor/bootstrap.min.js"></script>
|
||||
<script src="js/vendor/adminlte.min.js"></script>
|
||||
|
|
|
@ -0,0 +1,36 @@
|
|||
const pm2 = require('pm2')
|
||||
|
||||
const {
|
||||
WEB_CONCURRENCY,
|
||||
WEB_MEMORY
|
||||
} = process.env;
|
||||
|
||||
const options = {
|
||||
name: 'Facebook Survey',
|
||||
script: 'server.js',
|
||||
exec_mode: 'cluster',
|
||||
instances: WEB_CONCURRENCY || -1,
|
||||
max_memory_restart: `${WEB_MEMORY || 512}M`
|
||||
};
|
||||
|
||||
pm2.connect((err) => {
|
||||
if (err) {
|
||||
console.error(err);
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
pm2.start(options, (err) => {
|
||||
if (err) {
|
||||
return console.error('Error while launching the app', err.stack || err);
|
||||
}
|
||||
|
||||
// send logs to stdout
|
||||
pm2.launchBus((err, bus) => {
|
||||
console.log('[PM2] log streaming started');
|
||||
|
||||
bus.on('log:out', (packet) => console.log(`[App:${packet.process.name}] ${packet.data}`));
|
||||
|
||||
bus.on('log:err', (packet) => console.log(`[App:${packet.process.name}[Err] ${packet.data}`));
|
||||
});
|
||||
});
|
||||
});
|
Загрузка…
Ссылка в новой задаче