Skip to content

Instantly share code, notes, and snippets.

@nick-cheatwood7
Last active September 23, 2022 15:34
Show Gist options
  • Save nick-cheatwood7/2bea46a66a76f30024c86248d2708c9f to your computer and use it in GitHub Desktop.
Save nick-cheatwood7/2bea46a66a76f30024c86248d2708c9f to your computer and use it in GitHub Desktop.

Deployment Guide


For Ubuntu

Table of Contents

  1. Log into server
  2. Package Upgrades
  3. Create a new User/Disable root user
  4. Setup SSH keys
  5. Remove unneeded Ports
  6. Install Node/NPM
  7. Clone .git project
  8. Install project dependencies and test app
  9. Setup PM2
  10. Setup firewall
  11. Install/configure NGINX
  12. Connect Domain to Server (if applicable)
  13. Add SSL using Let's Encrypt
  14. All done!

1. Configure Server

  • copy the static ip address
  • In a terminal, login to the server like so:
# SSH into root machine
ssh root@ipAddress
  • Dismiss any warnings, then clear the terminal
clear

2. Package Upgrades

  • First, check for any available updates:
apt update
  • Install any available updates:
apt dist-upgrade
  • Then, reboot the machine so all updates go into effect.

  • Next, set up unattended upgrades:

apt install unattended-upgrades
  • Enable unattended upgrades:
dpkg-reconfigure --priority=low unattended-upgrades

3. Create a new User

  • Add a new user:
useradd -m -s /bin/bash <<username>> && passwd <<username>>
  • Confirm user was added to /home directory with:
ls /home
  • Verify that sudo is installed with:
which sudo

This should produce an output like /usr/bin/sudo. If it does not, install sudo with apt install sudo.

  • Setup new user with sudo group:
visudo
  • Groups in this file are shown like %<<groupName>>. To add the new user to a group:
usermod -aG sudo <<username>>
  • Confirm user was added to group:
groups <<username>>
  • Switch to new user account:
su - <<username>>
  • Make sure sudo works with new user:
sudo apt update

4. Setup SSH Keys

  • Close active ssh session:
exit
  • IMPORTANT: First check if you already have an SSH key on your local machine
ls -l ~/.ssh
  • If you do not already have an SSH key (id_rsa, id_rsa.pub), generate a new SSH key

  • Generate a new SSH key (only run if you do not already have an ssh key):

ssh-keygen
  • Copy your SSH key to Linode:
ssh-copy-id -i ~/.ssh/id_rsa.pub <<username>>@192.168.0.0 # replace ip address with ip address of Linode VPS
  • Confirm SSH access works:
ssh <<username>>@192.168.0.1 # again, replace this ip with ip of the VPS
  • Update SSH config:
sudo nano /etc/ssh/sshd_config
  • In the SSH config file, change the following from
...
PermitRootLogin yes
...

to

...
PermitRootLogin no
...
  • To allow users SSH access, add the following anywhere in the sshd_config file, replacing user_1, user_2, etc. with the users of your choice:
...
PermitRootLogin no
...
AllowUsers <<user_1>> <<user_2>> <<user_3>>
  • Lastly, write out the file and save your changes with CTRL+O and CTRL+X and restart the ssh service with:
sudo systemctl restart sshd
  • To verify SSH works correctly, open a new tab in your terminal and enter
ssh 192.168.0.0 # replace with ip of VPS

5. Remove unused ports

  • Check open ports:
sudo ss -atpu
  • To remove an unneeded port, run the following:
sudo apt remove <<name_of_port>>

6. Install Node/NPM

# Install Node
sudo apt install nodejs
# Confirm Node installed correctly
nodejs -v
# Install NPM
sudo apt install npm
# Verify installed version
npm -v
  • The installed Node version is likely outdated, but you can update by intalling NVM (Node Version Manager)
# Install cURL
sudo apt install curl
# Install NVM
curl https://raw.githubusercontent.com/creationix/nvm/master/install.sh | bash
# Load the NVM login script
source ~/.bashrc
# Install desired Node version
nvm install node # latest
# Tell NVM which Node version to use
nvm use node

7. Clone your project from GitHub

  • First create a webServices folder on the server and navigate to that folder
mkdir webServices && cd webServices
  • Next, clone your git repository into the /webServices folder
git clone myProject.git
  • If prompted for a password, you may need a Personal Access Token. If using GitHub, follow this guide.

8. Install dependencies and test app

cd myProject
npm install # install project dependencies
npm start # start the project
# stop app
ctrl+C

9. Setup PM2 to keep your app running

  • Install and initialize PM2:
npm install pm2@latest -g
pm2 start app.js # replace "app.js" with your entry point
  • Other PM2 Commands:
    • pm2 status: get the status of your app
    • pm2 list: list all processes
    • pm2 monit: monitor all processes launched by PM2
    • pm2 restart app.js: restart your app
    • pm2 stop app.js: stop your app
    • pm2 logs: view any console.logs() generated by your app
      • pm2 flush: flush any logs from the pm2 console
  • Configure PM2 to start on server reboot:
pm2 startup
  • To remove the startup script, run:
pm2 unstartup
  • Reboot the server for changes to take effect:
reboot
  • Confirm that PM2 is running:
pm2 status

10. Setup Firewall

  • Check status of firewall:
ufw status
  • Enable firewall:
ufw enable
  • Enable SSH with firewall:
ufw allow ssh
  • Check firewall status again:
ufw status
  • Allow HTTP through port 80:
ufw allow http
  • Allow HTTPS through port 443:
ufw allow https
  • Check firewall one more time:
ufw status

11. Install/Configure NGINX

  • Install NGINX:
sudo apt install nginx
  • Open the NGINX config file:
sudo nano /etc/nginx/sites-available/default
  • Edit the NGINX config file:
# /etc/nginx/sites-available/default
server {
  ...
  #server_name _; #if not using a custom domain
  server_name your_domain.com www.your_domain.com; #if using a custom domain
  ...
  location / {
          # First attempt to serve request as file, then
          # as directory, then fall back to displaying a 404
          proxy_pass http://localhost:5000; #whatever port your app runs on
          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;
  }
}
  • If running a GraphQL server, you may want to add the following:
# /etc/nginx/sites-available/default
server {
    ...
    location /graphql {
        proxy_pass http://localhost:4000/graphql;
    }
    ...
}
  • Save the NGINX config file:
# Write out the file
ctrl+O
# Do not modify filename
return/enter
  • Exit nano:
# Exit nano
ctrl+X
  • Confirm changes were saved successfully:
sudo nginx -t
  • Restart NGINX service:
sudo service nginx restart
  • Open a web browser to the server's IP Address (or domain, if applicable) and confirm the Node app loads as expected.

12. Connect Domain to Server (if available)

Coming soon.

13. Add SSL using Let's Encrypt

See up-to-date instructions here

14. All done!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment