Not Slide-ware: Hosting Your Node Project On AWS with Https

On May 18th 2020, I launched a start-up with a friend after quitting Amazon two days before. We have a company mission to create a positive impact to the local society, especially amid this difficult pandemic.

Personally, I also have the goal of going back to doing hands-on coding. The last 9 years of my 17 year professional life had been focused on management. I certainly learned a lot. I had helped many engineers and leaders develop their career. I had lead small and big teams to create many products.

And I had made a lot of slides! So now, I am back to hands-on software development. This is journey is anything but NOT “slide-ware!”.

An angular project in Visual Studio Code
An angular project in Visual Studio Code

So this is the first of the series to share what I learned along the way. In this post I will share my experience in hosting my node application on AWS with https using a combinations of AWS CloudFront and EC2. This will work even if you don’t own a custom domain of your own. In a follow-up post, I will also talk about how to host on ec2 with https using nginx without CloudFront. It’s likely these information is well known but I figure it is useful to share herejust in case it might save some time for someone.

Step 1 Create a node application and test on localhost

I will not go through the details for this step but there’s a lot of good articles on the internet. In my specific case, my localhost is a windows machine. I created an angular project using angular cli. I used github for my repository. I used visual studio code as my editor. I completed this step after verifying http://localhost:4200 is working.

Step 2 Create an AWS account from: https://aws.amazon.com/console/

Create an AWS account
Create an AWS account

Step 3 Create EC2 Instance

Log in to AWS console (link above). Go to the EC2 service portal and click Instances/Launch Stance. I suggest to use the default selection if you are just starting to experiment with AWS. The current default is t2.micro running Amazon Linux 2. This is free tier eligible https://aws.amazon.com/free.

EC2 portal
EC2 portal
Choose EC2 Types
Choose EC2 Types

Step 4 Serve your node application on the EC2 instance (assumes that you have chosen Amazon Linux 2 earlier).

4.1 ssh to your EC2 machine:

ssh -i<path to the pem file> ec2-user@<public IP address of your ec2 instance>

pem file can be created using “Key pairs” in the EC2 portal and this key pair is specified during the EC2 instance creation. The pem file needs to have the permission of 400. On windows this can be achieved using Properties->Security->Advanced->Disable Inheritance: then manually remove everything other than “Read” for the current user.

Create Key Pairs
Create Key Pairs

4.2 Install node:

curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.34.0/install.sh | bash

. ~/.nvm/nvm.sh

nvm install node

node -e “console.log(‘Running Node.js ‘ + process.version)”

4.3 Install git and pull from your repository (note AWS also has CodeCommit as an alternative to github).

sudo yum install git

git clone https://github.com/<path to your respository>

git pull origin master

4.4 Build and serve the node application (in this case, an angular project). These arguments ensure that the server is listening to all the incoming traffic to local host on port 4200.

npm install

ng serve — port 4200 — host 0.0.0.0 — disable-host-check

4.5 An optional step but useful later if you want to use nginx as reverse proxy without using CloudFront. Here, we install nginx just to route http port 80 to port 4200.

sudo amazon-linux-extras install nginx1

sudo service nginx start

sudo service nginx status

4.6 Configure to run nginx as a service

sudo chkconfig nginx on

sudo service nginx restart

4.7 Forwarding port 80 to port 4200

sudo nano /etc/nginx/nginx.conf (see below for the edit…nano is a convenient editor on the EC2 instance).

sudo service nginx restart

(in nginx.conf, we add the following:

server {
listen 80 default_server;
listen [::]:80 default_server;
server_name localhost;
root /usr/share/nginx/html;

# Load configuration files for the default server block.
include /etc/nginx/default.d/*.conf;

location / {
proxy_pass http://localhost:4200;
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;

}

4.8 install pm2 to keep ng serve running even after ssh session exit

npm install pm2 -g

pm2 start “ng serve — port 4200 — host 0.0.0.0 — disable-host-check”

pm2 save

pm2 list

Step 5 Add an inbound rules through the “Security Group” menu in the EC2 portal.

You want to open up the http port 80. You can further constrain the source but for now we are allowing any source.

At this point, you should be able to access your angular application using http://<Public DNS (IPv4) name, e.g. ec2-XXX.compute-1.amazonaws.com> (with the default http port 80).

Security Group
Security Group

Step 6 Create AWS CloudFront distribution and use it as a reverse proxy. Of course, CloudFront’s official purpose goes beyond this. It is a content delivery network that provides global distributed edge locations and provides caching as well.

Cloud Front
Cloud Front
Create CloudFront Distribution
Create CloudFront Distribution
Configure CloudFront Distribution
Configure CloudFront Distribution

Step 7 Now, success! You can access your app using https://XXX.cloudfront.net

CloudFront domain name
CloudFront domain name

Step 8 Invalid CloudFront cache when needed.

If you are doing prototyping, chances that your application files change rapidly. Since the CloudFront provides caching, you will need to sometimes invalid the cache.

CloudFront Invalidation
CloudFront Invalidation

Please feel free to leave a comment if you have any suggestions or questions.

Written by

beginning a new journey by launching my own startup in the middle of the pandemic. I am passionate about sharing my learning. www.linkedin.com/in/yupingwyp

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store