EC2 Server Setup

Introduction

This post will provide a step-by-step checklist for how to setup an EC2 (AWS Elastic Cloud Compute) instance to serve a Node.js web site or application. This approach uses as few third-party tools as possible. Obviously there's a plethora of ways one could configure an EC2 server instance. This approach is admittedly very manual, but it's also pretty simple and easy to follow.

The notion of "security through obscurity" is quite common in the world of web development. Server admins often configure their web servers to disclose as little information about themselves as possible. The fact that this post describes how I configure some of my servers could leave them more vulnerable to cyber attacks.

It is my hope that someone finds this information useful. Or, if you happen to spot a glaring flaw with this approach, please let me know in the comment section below.

Checklist

The following is a step-by-step checklist for setting up an EC2 server instance to host a public Node.js web application.

EC2 Setup Checklist
# EC2 Server Setup

## I. Launch Instance
[] From the AWS console, launch a new EC2 instance (latest version of Ubuntu Server).
[] Configure security group to allow http/https traffic (ports 80 and 443 respectively) from all IP addresses.
[] Configure security group to allow SSH (port 22) traffic from your IP address (this will need to be updated as your IP address changes).
[] Create an AWS keypair and store the keypair on your machine with chmod 600 file privileges.
[] Take note of the public IP address given to the new EC2 instance.

## II. Configure Instance
[] Using the downloaded keypair, SSH into the new EC2 instance using its public IP address.
[] Update the server's packages (sudo apt update).
[] Install nvm (curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.1/install.sh | bash).
[] Use nvm to install the desired version of node (nvm install x.x.x).
[] Create a default nvm alias to the desired version (nvm alias default x.x.x).
[] Confirm nvm is configured correctly (nvm ls).
[] Create project folder structure in the /opt directory (sudo mkdir /opt/project-folder).
[] Make the ubuntu user the owner of the project folder (sudo chown -R ubuntu /opt/project-folder).
[] Create project subfolders (mkdir -p /opt/project-folder/dist && mkdir -p /opt/project-folder/public && mkdir -p /opt/project-folder/secrets)
[] From your local machine, SCP the built project code to the server's dist folder (scp -i ~/keypair.pem -r ~/local/path/to/project/dist/* ubuntu@:/opt/project-folder/dist).
[] From your local machine, SCP the public folder (scp -i ~/keypair.pem -r ~/local/path/to/project/public/* ubuntu@:/opt/project-folder/public).
[] From your local machine, SCP the package.json file to the server's project-folder (scp -i ~/keypair.pem ~/local/path/to/project/package.json ubuntu@:/opt/project-folder).
[] Back on the server, run npm install from /opt/project-folder.
[] Allow the ubuntu user to run node on ports 80 and 443 (sudo apt-get install libcap2-bin && sudo setcap cap_net_bind_service=+ep /home/ubuntu/.nvm/versions/node/x.x.x/bin/node)
[] Test the server with npm run prod (or whatever command you use to run Node.js in production).
[] Stop the node server.
[] From your DNS provider, point the site's A record to the EC2 instance's public IP address.
[] Install the certbot package (sudo apt install certbot).
[] Use certbot to create an SSL certificate. Remember to change yourdomain.com. (sudo certbot certonly --standalone --agree-tos --preferred-challenges http -d yourdomain.com).
[] Copy the certs to the project secrets folder (sudo cp /etc/letsencrypt/archive/yourdomain.com/fullchain1.pem /opt/project-folder/secrets/cert.pem && sudo cp /etc/letsencrypt/archive/yourdomain.com/privkey1.pem /opt/project-folder/secrets/private-key.pem).
[] Update the permissions of the secrets folder (chmod -R 600 /opt/project-folder/secrets).
[] Test the node server again with npm run prod.
[] If everything looks good, have the server run in the background and log its output to a text file (nohup npm run prod > traffic.log 2>&1 &).

## III. Pushing Updates
[] Stop the running node process (ps -A | grep node, then kill the node pid).
[] Archive the previous traffic log (mv /opt/project-folder/traffic.log /opt/project-folder/traffic.log.x).
[] From your local machine, SCP the built project code to the server's dist folder (scp -i ~/keypair.pem -r ~/local/path/to/project/dist/* ubuntu@:/opt/project-folder/dist).
[] From your local machine, SCP the public folder (scp -i ~/keypair.pem -r ~/local/path/to/project/public/* ubuntu@:/opt/project-folder/public).
[] Back on the server, restart the node process (nohup npm run prod > traffic.log 2>&1 &).

Conclusion

Admittedly it's not the most sophisticated setup process in the world, but it gets the job done for small one-off Node.js applications hosted from EC2. If you'd like to share your own server configuration tips, you're invited to comment below.

Comments

There are no public comments at this time.


Post a Comment