Skip to content

Instantly share code, notes, and snippets.

@Shahzad6077
Forked from carlssonk/deploy_node_do.md
Created August 16, 2022 22:59
Show Gist options
  • Select an option

  • Save Shahzad6077/191a4eceb832de3fcab872cf38d4f2b8 to your computer and use it in GitHub Desktop.

Select an option

Save Shahzad6077/191a4eceb832de3fcab872cf38d4f2b8 to your computer and use it in GitHub Desktop.
Deploy node.js app to DigitalOcean

Deploy Node.js Application to DigitalOcean

This step by step tutorial will show you how to set up a Node.js server with MongoDB to DigitalOcean using PM2, NGINX as reverse proxy and a SSL from LetsEncrypt. We will also add a custom domain name.

Prerequisites

Create Droplet & Generate SSH Key

  1. Create New Project/Create New Droplet
  2. Choose Ubuntu, Choose your desired plan & country
  3. Click on New SSH Key
  4. Open PuTTyGen and generate a new RSA Key
  5. Copy the key in the input field and add it to your droplet, Add SSH Key
  6. IMPORTANT Be sure to save the public key as .txt and your private key as .ppk on your computer, you will need these later
  7. Create Droplet

Configure PuTTY

  1. Open PuTTY
  2. Add your droplets IP Adress to 'Host Name (or IP Adress)'
  3. In Connection -> Data, set username to "root"
  4. In SSH -> Auth, load your privatekey.ppk that you created from last step
  5. Set a session name and SAVE

Create New User

  1. Login to your server, click yes if first time connecting to server

  2. Add user and assign him to the sudo group:

adduser [username]
usermod -aG sudo [username]

You can check to make sure that user was added in sudo group id [username]

  1. Login as that user:
sudo su - [username]

Authorize Key For New User

  1. Make new directory:
mkdir ~/.ssh
  1. Change permission:
chmod 700 ~/.ssh
  1. Create and go into new file:
nano ~/.ssh/authorized_keys
  1. Copy ssh key from publickey.txt (exclude "Comment: rsa-key-date") Inside authorized_keys on the first line type: "ssh-rsa" space and add your key, also make everything in one line.

    It should look something like this now: “ssh-rsa AAAABaxASDVAV17547DFDVGDVG...”

    Save file: Ctrl+X & Y

  2. Set permission for that file:

chmod 600 ~/.ssh/authorized_keys
  1. Restart service:
sudo service ssh restart
  1. Exit terminal and login as new user. Load config, click Data and change root to your [username].

Disable Root & Password Login AND Change SSH-port

Disable Root & Password Login

  1. Go into ssh config file:
sudo nano /etc/ssh/sshd_config
  1. Search for PermitRootLogin: Ctrl+W and type "PermitRootLogin"
  2. Set PermitRootLogin to "no"
  3. Search for PasswordAuthentication: Ctrl+W and type "PasswordAuthentication"
  4. Set PasswordAuthentication to "no"

Change SSH-port

A lot of attacks on web servers occur by scripts trying to get into the default port for SSH, port 22. Therefore, we change this, feel free to take a five-digit port (difficulty guessing), but not higher than 65535. (Also: Note the number should not start with 0.)

  1. Find the row Port 22 and change it to another port, eg. XXXXX
    Important: Make sure to remember the Port you changed to
# If the row start with a '#' you should remove it
# Ex.
Port 25565

Exit with Ctrl+X and Save 7. Reboot session:

reboot
  1. Close terminal and open PuTTY
  2. Now in the port input, type in your new port

Note that if you try to open the terminal with another port like 22 you will get a "connection refused error".

  1. Save and open terminal

Enable Firewall

Note: to enable firewall you need to be on the root user. Type sudo -i or sudo -s to switch to the root user
Type su - [username] to switch back to your user after enabling firewall

  1. Enable firewall, ssh, http & https:
ufw enable
ufw allow ssh
ufw allow http
ufw allow https

To check your firewall status: ufw status

Install packages

  1. Update packages:
sudo apt update
  1. Install latest version of nodejs:

Note: this is version 14 we are installing, check nodejs homepage and see if there is a newer version, pick the one that says recommended for most users, and change "14" in this command to the new version

curl -sL https://deb.nodesource.com/setup_14.x | sudo -E bash -
  1. Install nodejs & npm:
sudo apt-get install nodejs

You can make sure they are installed: "npm -v" and "node -v"

Install PM2

  1. Install pm2 globally:
sudo npm install -g pm2
  1. Start server: pm2 start index.js or pm2 start npm -- start
  2. App should now be running on the droplets ip adress:

ex.165.227.216.5:8080

NGINX

  1. Install nginx:
sudo apt install nginx
  1. Go into default folder:
sudo nano /etc/nginx/sites-available/default
  1. Remove everything inside the location brackets and add proxies:
location / {
	
	proxy_pass http://localhost:8080; #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;
	
}

Note: if localhost does not work use ip address from your droplet.

  1. Above the location we have server_name_;. Set the server name to your domain name if you want to use a domain name for this app. It should look like this server_name mywebsite.com www.mywebsite.com
  2. Exit and save: Ctrl+X & Y
  3. Check so nginx is configured properly sudo nginx -t. It should say something like the test is successful
  4. Now restart the service sudo service nginx restart

Clone App from github

If your project is not on github, upload it to github so we can clone it to your droplet

  1. Create ssh key for github:
ssh-keygen -t rsa -C '[email protected]'
  1. Open WinSCP and choose import droplet & login
  2. In /home/[username]/ add .ssh because its hidden by default, so go into the /home/[username]/.ssh directory
  3. Drag over the id_rsa.pub file to the document folder and open the file
  4. Copy the key and add it to ssh in GitHub
  5. Now in your droplets terminal clone the project from github:
git clone [email protected]:user/your/repository
  1. type ls and boom your project is there
  2. cd into your projext and type npm install to install all packages that your project contains

Add domain

  1. First buy your domain through preferred service: ex, namecheap, godaddy.
  2. Then in DigitalOcean go to the networking tab and add your domain
  3. Where it says HOSTNAME you will add a "@" and at WILL DIRECT TO you want to put your droplet
  4. Click on Create Record.

The record you are creating is "A"

  1. Create a Record for the www version, so do the same but replace "@" with "www"
  2. Go to your domain name provider. Click on your domain or click manage domain and go to nameservers and click Custom DNS
  3. Add 3 nameservers. It should look like this:
    • ns1.digitalocean.com
    • ns2.digitalocean.com
    • ns3.digitalocean.com
  4. Click save

Note: it can take up to a couple of hours for the domain name to take effect, but usually it takes 5-15 minutes

Add SSL with LetsEncrypt (enables HTTPS)

Note: certbot is deprecated. So its best to install snapshot of certbot so it stays up to date. We will install certbot by following these instructions This installation is for web server on Nginx with Ubuntu 20.04

  1. Make sure everything is up to date sudo apt-get update
  2. You should already have snapd installed, so make sure its up to date with this command:
sudo snap install core; sudo snap refresh core
  1. Before installing certbot, remove it so we can install certbot snap, we dont want them to collide:
sudo apt-get remove certbot
  1. Now install certbot:
sudo snap install --classic certbot
  1. Prepare cerbot with your domains, it should look like this:
sudo certbot --nginx -d mywebsite.com -d www.mywebsite.com

This command gives you a certificate & Certbot edits your Nginx configuration automatically to serve it, turning on HTTPS access in a single step 6. Almost done, but this certificate will expire in 90 days, to renew it after every 90 days type this command:

sudo certbot renew --dry-run

Congratulations you are done! Happy Hacking :D

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