This tutorial has been specifically written for Ubuntu 16.4, although it may apply to other versions as well. For all commands and code examples, replace {{text}}
with values specific to your project.
Create Server
If you haven't already, in your hosting company's control panel, create a new Server.
Note: Make sure to open Ports 80 and 443 on the Server Firewall.
Install Server Software
Become an administrator
sudo su
Prepare for installation
apt-get update
apt-get upgrade
apt-get autoremove
Install Node
curl -sL https://deb.nodesource.com/setup_9.x | sudo -E bash -
apt-get install -y nodejs
cd /etc
mkdir node
Install Nginx
apt-get install nginx
Install MongoDB (Optional)
Note: (Instructions are from https://docs.mongodb.com/manual/tutorial/install-mongodb-on-ubuntu/)
sudo apt-key adv --keyserver hkp://keyserver.ubuntu.com:80 --recv 2930ADAE8CAF5059EE73BB4B58712A2291FA4AD5
echo "deb [ arch=amd64,arm64 ] https://repo.mongodb.org/apt/ubuntu xenial/mongodb-org/3.6 multiverse" | sudo tee /etc/apt/sources.list.d/mongodb-org-3.6.list
sudo apt-get update
sudo apt-get install -y mongodb-org
sudo service mongod start
Configure Server Software
Configure Nginx
cd /etc/nginx/sites-available/
touch {{site name}}
vim {{site name}}
Paste this into the file. Save by pressing ESC, and entering :wq
.
server {
listen 80;
server_name {{site url}};
charset UTF-8;
location / {
root /etc/node/{{site root}}/{{public folder}};
try_files $uri $uri/ @dynamic;
expires max;
access_log off;
}
location @dynamic {
proxy_pass http://localhost:{{site port}};
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;
}
}
Add GZip Compression to /etc/nginx/nginx.conf. Uncomment these lines, and update. This step is optional.
gzip on;
gzip_disable "msie6";
gzip_vary on;
gzip_proxied any;
gzip_comp_level 6;
gzip_buffers 16 8k;
gzip_http_version 1.1;
gzip_min_length 256;
gzip_types text/plain text/css application/json application/javascript text/xml application/xml application/xml+rss text/javascript application/vnd.ms-fontobject application/x-font-ttf font/opentype image/svg+xml image/x-icon;
Update Enabled Sites
ln -s /etc/nginx/sites-available/{{site name}} /etc/nginx/sites-enabled/{{site name}}
nginx -t
nginx -s reload
Prepare for Deployment
Create Deployment User
adduser deployment
usermod -aG sudo deployment
chown -R deployment /etc/node/
chgrp -R deployment /etc/node/
su deployment
Create project folder
mkdir -p /etc/node/{{site root}}
Create SSH Keys
cd /home/deployment
ssh-keygen -t rsa -C "deployment@{{site url}}" -b 4096
Store the output of these two commands for use
cat ~/.ssh/id_rsa.pub
cat ~/.ssh/id_rsa
Install SSH Keys
ssh-copy-id {{site url}}
Exit back to admin user
exit
Set Up Deployment
Create a GitLab account and Log In.
In GitLab, go to Profile -> Settings -> SSH Keys
. Enter the value of ~/.ssh/id_rsa.pub
into Key
. Title
should populate automatically. Click Add key
.
Create a Project. In your project, go to Settings -> CI / CD
. Expand Secret variables
. Enter STAGING_PRIVATE_KEY
into Key
. Enter the value of ~/.ssh/id_rsa
into Value
. Click Add new variable
.
Create GitLab Deployment
In your project, create the file .gitlab-ci.yml
. Paste into that file:
image: node:latest
services:
cache:
paths:
- node_modules/
test_async:
script:
- npm install
- npm test
before_script:
- 'which ssh-agent || ( apt-get update -y && apt-get install openssh-client -y )'
- mkdir -p ~/.ssh
- echo "$STAGING_PRIVATE_KEY" | tr -d '\r' > ~/.ssh/id_rsa
- chmod 600 ~/.ssh/id_rsa
- eval "$(ssh-agent -s)"
- ssh-add ~/.ssh/id_rsa
- '[[ -f /.dockerenv ]] && echo -e "Host *\n\tStrictHostKeyChecking no\n\n" > ~/.ssh/config'
staging:
type: deploy
script:
- npm install
- npm run dev
- tar -zcf ../build.tar.gz ./ --exclude='.git/' --exclude='build.tar.gz'
- ssh deployment@{{site url}} "
cd /etc/node &&
rm -rf _tmp &&
mkdir -p _tmp/{{site root}}_new"
- scp ../build.tar.gz deployment@{{site url}}:/etc/node/_tmp
- ssh deployment@{{site url}} "
cd /etc/node/_tmp &&
tar -xzf build.tar.gz -C {{site root}}_new &&
rm build.tar.gz &&
mv /etc/node/{{site root}} {{site root}}_old &&
mv {{site root}}_new /etc/node/{{site root}} &&
cd ../ &&
rm -rf _tmp"
only:
- master
Commit the file, and allow GitLab to deploy it.
Start Node Server
Install Node Site Runner
npm install -g pm2
su deployment
touch process.yml
vim process.yml
Paste this into the file. Save by pressing ESC, and entering :wq
.
apps:
- script: {{site root}}/{{main js file}}
instances: 4
exec_mode: cluster
watch: true
env:
NODE_ENV: development
env_production:
NODE_ENV: production
Exit back to admin
exit
Create SSL Certificate
Create Certificate
apt-get install software-properties-common
add-apt-repository ppa:certbot/certbot
apt-get update
apt-get install python-certbot-nginx
certbot certonly --webroot -w /etc/node/{{site root}}/{{public folder}}/ -d {{site url}}
certbot --nginx
Renew Certificate
certbot renew