Steps to setup a Node.js App to AWS Ubuntu server using, NVM, PM2, NGINX as a reverse proxy and SSL from LetsEncript
-
Create an Ubuntu server on AWS with EC2
-
Creating sudoers user (don’t use root)
-
Prevent root user login via SSH and change the SSH port
-
Open and edit /etc/ssh/sshd_config:
PermitRootLogin no Port 10201
-
Restart SSH service
-
-
Install ZSH (Optional)
- Connect to your EC2 instance
- Install zsh :
sudo apt-get update && sudo apt-get install zsh - Edit your passwd configuration file to tell which shell to use for user
ubuntu:sudo vim /etc/passwd - Look for
ubuntuuser, and replacebin/bashbybin/zsh - Install OhMyZsh :
sh -c "$(curl -fsSL https://raw.githubusercontent.com/ohmyzsh/ohmyzsh/master/tools/install.sh)" - Disconnect from your instance and reconnect it.
-
Install NVM https://github.com/nvm-sh/nvm
-
Install Node.js using NVM
nvm install node #Install the latest available version nvm use node #Use the latest version nvm install --lts #Install the latest LTS version nvm use --lts #Use the latest LTS version
-
Install Yarn (optional) https://yarnpkg.com/getting-started/install
-
Create SSH key https://docs.github.com/en/authentication/connecting-to-github-with-ssh/generating-a-new-ssh-key-and-adding-it-to-the-ssh-agent
-
Add SSH key to Github https://docs.github.com/en/authentication/connecting-to-github-with-ssh/adding-a-new-ssh-key-to-your-github-account
-
Clone your project from Github through SSH
git@github.com:yourproject.git
-
Add Environmental Variables (if apply)
-
Install dependencies and test app
cd yourproject npm install npm start (or whatever your start command) # stop app ctrl+C
-
Setup PM2 process manager to keep your app running https://pm2.keymetrics.io/docs/usage/quick-start/
sudo npm i pm2 -g pm2 start app (or whatever your file name) # Other pm2 commands pm2 show app pm2 status pm2 restart app pm2 stop app pm2 logs (Show log stream) pm2 flush (Clear logs) # To make sure app starts when reboot pm2 startup ubuntu
You should now be able to access your app using your IP and port. Now we want to setup a firewall blocking that port and setup NGINX as a reverse proxy so we can access it directly using port 80 (http)
-
Setup ufw firewall
sudo ufw enable sudo ufw status sudo ufw allow ssh (Port 22) sudo ufw allow http (Port 80) sudo ufw allow https (Port 443) -
Install NGINX and configure https://www.digitalocean.com/community/tutorials/how-to-install-nginx-on-ubuntu-20-04
sudo apt install nginx sudo nano /etc/nginx/sites-available/default
Add the following to the location part of the server block
server_name yourdomain.com www.yourdomain.com; location / { 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; }# Check NGINX config sudo nginx -t # Restart NGINX sudo service nginx restart
-
Add domain DNS configuration
- Add an A record for @ and for www to your server IP address
-
Add SSL with LetsEncrypt
sudo add-apt-repository ppa:certbot/certbot sudo apt-get update sudo apt-get install python-certbot-nginx sudo certbot --nginx -d yourdomain.com -d www.yourdomain.com # Only valid for 90 days, test the renewal process with certbot renew --dry-run