Tested on 18/05/2019
- Vagrant
- VirtualBox
- npm
- express-generator
npm install express-generator -g
Hogan.js is the mustache syntax from twitter, very straight forward.
express --view=hogan my-node-app
- Create
vagrant
folder - Add
.vagrant/
to.gitignore
From the empty vagrant
folder
# install Vagrant box
# https://app.vagrantup.com/boxes/
vagrant box add ubuntu/xenial64
vagrant init ubuntu/xenial64
vagrant up
vagrant status
vagrant ssh
Vagrantfile
is written in Ruby.- In
Vagrantfile
, uncommentconfig.vm.network "private_network", ip: "192.168.33.10"
, you can have any IP you want, let's say55.55.55.55
- Add shared folder,
config.vm.provision "file", source: "./shared", destination: "$HOME/shared"
vagrant reload
- Use
vagrant reload --provision
to copy file from local shared folder to VM
From VM:
sudo apt-get update
sudo apt-get install nginx
sudo service nginx start
Run sudo service nginx stop
to stop the service
lsb_release -a
: check Linux version
C:\Windows\System32\Drivers\etc\hosts
sudo vim /etc/hosts
In hosts
file, add line 55.55.55.55 dev.mynodeapp.com
to the bottom
From VM:
cd ~
# Current LTS version: 10.x
curl -sL https://deb.nodesource.com/setup_10.x -o nodesource_setup.sh
sudo bash nodesource_setup.sh
sudo apt-get install nodejs -y
nodejs -v
curl -sS https://dl.yarnpkg.com/debian/pubkey.gpg | sudo apt-key add -
echo "deb https://dl.yarnpkg.com/debian/ stable main" | sudo tee /etc/apt/sources.list.d/yarn.list
sudo apt-get update && sudo apt-get install yarn
From VM:
sudo useradd --create-home -s /bin/bash deploy
sudo adduser deploy sudo
sudo passwd deploy
username: deploy
password: deploy-password
From VM:
mkdir .ssh
Copy ssh key to remote server
scp ~/.ssh/id_rsa.pub deploy@url.com:~/.ssh/authorized_keys
curl -sS https://dl.yarnpkg.com/debian/pubkey.gpg | sudo apt-key add -
echo "deb https://dl.yarnpkg.com/debian/ stable main" | sudo tee /etc/apt/sources.list.d/yarn.list
sudo apt-get update && sudo apt-get install yarn
- Copy files from local machine to
./vagrant/shared/my-node-app
folder. (Which we previously added provision to). - Excluding the
node_modules
andvagrant
folders. - Run
vagrant reload --provision
to copy the files
From VM
mv ~/shared/my-node-app ~
cd ~/my-node-app
yarn
yarn start
Set environment variable on Utuntu
DEBUG=my-node-app:server yarn start
Open another SSL connection
curl http://localhost:3000
If you see the html page, the app is working properly on Vagrant VM now.
PM2: a process manager
sudo npm install -g pm2
# start application
pm2 start ./bin/www
# Save processes for Restart on Boot **IMPORTANT!!!**
pm2 save
# generate startup script
pm2 startup systemd
# remove from startup
pm2 unstartup systemd
# check systemctl
systemctl status pm2-vagrant
PM2 commands
pm2 stop <app_name_or_id>
pm2 restart <app_name_or_id>
pm2 delete www
pm2 delete all
pm2 info <app_name_or_id>
# show process monitor
pm2 monit
This is the easiest way to use process.env
environment variables
create a pm2.config.js
file under project root directory
touch pm2.config.js
vim pm2.config.js
module.exports = {
apps: [
{
name: 'my-node-app',
script: './bin/www',
watch: true,
env: {
PORT: 3000,
NODE_ENV: 'production'
},
env_dev: {
PORT: 3000,
NODE_ENV: 'development'
}
}
]
}
pm2 start pm2.config.js
will start the app with defaultenv
pm2 start pm2.config.js --env dev
will start the app in dev mode- Don't forget
pm2 save
!!!
Node is running single core
by default.
Create cluster.js
file:
const cluster = require('cluster')
if (cluster.isMaster) {
const cpuCount = require('os').cpus().length
for (let i = 0; i < cpuCount; i += 1) {
cluster.fork()
}
cluster.on('exit', function() {
cluster.fork()
})
} else {
require('./bin/www')
}
However, we can simply run multiple node instance in PM2.
Add these configuration to pm2.config.js
file
{
apps : [{
// ...
instances : "max",
exec_mode : "cluster"
}]
}
Save the change, in pm2 list
will show 2 instance in vagrant VM (2 core be default).
sudo apt-get update && sudo apt-get install nginx -y
cd /etc/nginx/sites-available
sudo vim default
i
: switching to insert mode- ESC: switching to command mode
:q
: quit (:q!
: quit without save;:wq
: write and quit):w
: write
In /etc/nginx/nginx.conf
The # of cores your CPU is running
worker_processes: auto;
Check the # of cores
cat /proc/cpuinfo
Add proxy configuration into server
block in /etc/nginx/sites-available/default
file
server {
...
location / {
proxy_pass http://localhost:8080;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection 'upgrade';
proxy_set_header Host $host;
proxy_cache_bypass $http_upgrade;
}
}
To map another url, e.g. http://dev.mynodeapp.com/app2
server {
...
location / {
...
}
location /app2 {
proxy_pass http://localhost:3000;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection 'upgrade';
proxy_set_header Host $host;
proxy_cache_bypass $http_upgrade;
}
}
Testing current configuration
sudo nginx -t
Restart nginx
sudo systemctl restart nginx
ab -c 40 -n 1000 http://dev.mynodeapp.com/