Skip to content

Instantly share code, notes, and snippets.

@tusharf5
Last active December 5, 2023 03:36
Show Gist options
  • Star 3 You must be signed in to star a gist
  • Fork 3 You must be signed in to fork a gist
  • Save tusharf5/5a629e44f8749aa2a39ad36fa7d84d91 to your computer and use it in GitHub Desktop.
Save tusharf5/5a629e44f8749aa2a39ad36fa7d84d91 to your computer and use it in GitHub Desktop.
Starter Script or User Data (NGINX as Reverse Proxy for Node.js with PM2) [Amazon Linux 2]

Starter Script or User Data (NGINX as Reverse Proxy for Node.js with PM2) [Amazon Linux 2]

  • Install Git
  • Install Nginx
  • Setup Nginx as a Reverse Proxy for your Node.js Application
  • Install Node using NVM
  • Install PM2
  • Run a Dummy API Server Using express
  • Start the Server using PM2
  • Auto Start PM2 after a server reboot.

Login to Ec2 Instance - ssh ec2-user@54.221.355.461 -i ~/.ssh/temp-personal.pem

This script is run by root user. But some part (subscript) of it is run as ec2-user so it can install node.js without sudo.

Don't forget to allow HTTP Port 80 in your Security Group.

The following script will completely overwrite your EC2 server's NGINX configuration to setup a reverse proxy.

Don't forget to add a backslash \ if you want to use $ inside the subscript.

You can check the output of this script cat /var/log/cloud-init-output.log or cat /var/log/cloud-init.log.

#!/bin/bash

cd /home/ec2-user/

## Updating Packages
sudo yum update -y

## Installing Git Client
sudo yum install git -y

## Installing Cronttab
sudo yum install crontabs -y
sudo chkconfig crond on
sudo service crond start

## Install Python
sudo yum install python3.x86_64 -y

## For system to be able to compile software, you need many development tools, such as make, gcc, and autoconf.
sudo yum groupinstall "Development Tools" -y

## Required By MongoDB
sudo yum install krb5-devel -y
sudo yum install cyrus-sasl cyrus-sasl-plain cyrus-sasl-gssapi krb5-libs libcurl libpcap net-snmp openldap openssl -y

## Installing Nginx
sudo amazon-linux-extras install nginx1.12 -y

## Modifying Nginx Server Configuration
sudo cat > /etc/nginx/nginx.conf <<EOL
user nginx;
worker_processes auto;
include /usr/share/nginx/modules/*.conf;
events {
    worker_connections 1024;
}
http {
    sendfile on;
    tcp_nopush on;
    tcp_nodelay on;
    keepalive_timeout 65;
    types_hash_max_size 2048;
    error_log /dev/null;
    access_log /dev/null;
    include /etc/nginx/mime.types;
    default_type application/octet-stream;
    upstream express_server {
        server 127.0.0.1:8080;
        keepalive 64;
    }
    server {
        listen 80 default_server;
        listen [::]:80 default_server;
        server_name _;
        location / {
            proxy_set_header X-Forwarded-For \$proxy_add_x_forwarded_for;
            proxy_set_header X-Real-IP \$remote_addr;
            proxy_set_header Host \$http_host;
            proxy_set_header Upgrade \$http_upgrade;
            proxy_set_header Connection "upgrade";
            proxy_http_version 1.1;
            proxy_pass http://express_server/;
            proxy_redirect off;
            proxy_read_timeout 240s;
        }
    }
}
EOL

## Starting Nginx Services
sudo chkconfig nginx on
sudo service nginx start
sudo service nginx restart

## Writing the Script to be run as ec2-user
cat > /tmp/subscript.sh << EOF

## Installing NVM
curl -sL https://raw.githubusercontent.com/nvm-sh/nvm/v0.34.0/install.sh | bash
 
echo 'export NVM_DIR="/home/ec2-user/.nvm"' >> /home/ec2-usr/.bashrc
echo '[ -s "\$NVM_DIR/nvm.sh" ] && . "\$NVM_DIR/nvm.sh"  # This loads nvm' >> /home/ec2-user/.bashrc
 
## Dot source the files to ensure that variables are available within the current shell
. /home/ec2-user/.nvm/nvm.sh
. /home/ec2-user/.bashrc
 
## Install Node.js
nvm install v10.16.3
nvm use v10.16.3
nvm alias default v10.16.3

## Installing Global PM2 package
npm install -g pm2

## Installing Yarn
curl -o- -L https://yarnpkg.com/install.sh | bash
export PATH="\$HOME/.yarn/bin:\$HOME/.config/yarn/global/node_modules/.bin:\$PATH"

## Creating API Directory
mkdir api
cd api

## You'd probably want to connect to your git repository here and
## pull the master branch, then build and run it.
## But we'll create a mini express server
yarn init -y
yarn add express

cat > ./app.js <<EOL
var express = require('express');
var app = express();
app.get('/', function(req, res){
   res.send("Hello World!");
});
app.listen(3001);
EOL

## Starting the Server
pm2 start app.js

## Saving the current state of pm2
pm2 save

## Adding Cron Job to Auto Restart PM2 on Reboot
cat <(crontab -l) <(echo "@reboot /home/ec2-user/.nvm/versions/node/v10.16.3/bin/node /home/ec2-user/.nvm/versions/node/v10.16.3/bin/pm2 resurrect") | crontab -

EOF

## Changing the owner of the temp script so ec2-user could run it 
chown ec2-user:ec2-user /tmp/subscript.sh && chmod a+x /tmp/subscript.sh

## Executing the script as ec2-user
sleep 1; su - ec2-user -c "/tmp/subscript.sh"
@tusharf5
Copy link
Author

tusharf5 commented Aug 19, 2019

I had to add backslash \ to all the $s used in the script as shell attempts to read it as a variable.

Also, I need to test if the setup works after a reboot. Working now. Make sure to pm2 save every time you deploy a new version.

@tusharf5
Copy link
Author

Add this line to stop aws cloudwatch agent which collects the logs sudo service awslogsd stop.

Note - These two lines turn off Nginx Logging.

error_log /dev/null;
access_log /dev/null;

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