Skip to content

spontit/web-app-tutorial

Repository files navigation

This tutorial Node.JS app can be accessed here.

Introduction

This node web app is a React web app served by Express. It is dockerized and then published on AWS Elastic Beanstalk.

Create React App and Serve on Express

Install dependencies

First, create a react app named 'my-app' and go into the folder:
npx create-react-app my-app
cd my-app
Then, install and save express:
npm install express --save
Once you have finished the above steps, you may run the React app in the development mode: npm run start

Serve React app

Create 'server.js' file as following and save it in the project root folder:

const express = require('express');
const bodyParser = require('body-parser')
const path = require('path');
const app = express();
app.use(express.static(path.join(__dirname, 'build')));

const PORT = process.env.PORT || 8080;
const HOST = '0.0.0.0';

app.get('/hello', (req, res) => {
  return res.send('Hello World!')
});

app.get('/', (req, res) => {
  res.sendFile(path.join(__dirname, 'build', 'index.html'));
});

app.listen(PORT);
console.log(`Running on http://${HOST}:${PORT}`);

In package.json file, add:
"proxy": "http://localhost:8080"
After finishing the above steps, you may run build on your React app:
npm run build
and run Express to serve the React app:
node server.js

Dockerize the app

To use docker, sign up on Docker and install Docker and/or Docker Desktop as needed. Once Docker installation is complete, create a file named 'Dockerfile' by running:
touch Dockerfile

Edit Dockerfile

In the Dockerfile, specify the image you want to build from. The latest image number for node.js app is available on the Docker Hub.
FROM node:14
Next, create the working directory of your app:
WORKDIR /usr/src/app
Then, copy your package.json and install the dependencies by adding the following lines:
COPY package*.json ./
RUN npm install
To bundle the source code in your app, add:
COPY . .
Your app runs on port 8080, so add this line:
EXPOSE 8080
End by specify the command for starting your app:
CMD [ "node", "server.js" ]
The complete Dockerfile should look like this:

FROM node:14

WORKDIR /usr/src/app

COPY package*.json ./

RUN npm install

COPY . .

EXPOSE 8080

CMD [ "node", "server.js" ]

Add .dockerignore file

Create .dockerignore file and add the lines as following: node_modules npm-debug.log This will prevent local node modules and debug logs from being copied into the Docker image. Screenshot of .dockerignore: screenshot-dockerignore

Build, run, and push the docker image

To build the docker image, run the following command:
docker build -t <your username>/<your app name> .
To run the built image on port 49160, run:
docker run -p 49160:8080 -d <your username>/<your app name>
The -p flag redirects a public port to a private port inside the container.
To confirm that the image is running, run:
docker ps
In order to deploy a remote docker image to AWS Elastic Beanstalk, push the image to Docker Hub:
docker push <your username>/<your app name>:latest

Learn More
For reference, Node.JS has published a guide on how to dockerize a Node.JS app here.

Deploy Docker Container on AWS Elastic Beanstalk

If you have not used AWS Elastic Beanstalk before, you can get started by reading the documentations.

Create Dockerrun.aws.json

Create Dockerrun.aws.json file as following:

{
  "AWSEBDockerrunVersion": "1",
  "Image": {
    "Name": "your-docker-username/repo-name",
    "Update": "true"
  },
  "Ports": [
    {
      "ContainerPort": "8080"
    }
  ]
}

This includes information on the remote docker image that Elastic Beanstalk should pull. We will then create a Elastic Beanstalk app and upload this file.

Set up Elastic Beanstalk app and deploy

To set up your app on Elastic Beanstalk, first, go to Elastic Beanstalk console -> Applications, and click on "Create a New Application".
Enter your application name:
screenshot-ebcreateapp
Click on "Create a New Environment" for the app you just created:
screenshot-ebcreateenvironment
Select 'Web server environment' for this app:
screenshot-ebenvironment
For 'Platform', Choose 'Docker', and the platform branch and version as you like.
For 'Application code', choose 'Upload your code', and upload Dockerrun.aws.json you just created:
screenshot-ebplatform
screenshot-upload-dockerrun
Navigate to 'Configure more options', and choose a preset configuration or create a configuration that contains a load balancer.
screenshot-configuremore
The app will be created in a moment and will be deployed at the elasticbeanstalk address:
screenshot-ebcreated
Learn More
For reference, AWS has documentations on deploying docker container on AWS Elastic Beanstalk.

Connect to a Custom Domain (Google Domains)

Add CNAME records

You may purchase a domain address on any platform as you like. This example will demonstrate how to connect your deployed app with an address purchased from Google Domains.
First, choose a domain name you like and purchase it.
The domain address will show in your Google Domains account after purchase. Go to 'DNS' on the left menu, and scroll to 'Custom resource records'
Add a CNAME record, put in your elastic beanstalk app address as 'data' and 'www' as 'name':
screenshot-cname

Add name servers

We also need to add custom name servers on 'DNS' page. We will do this in "Name Servers" section.
screenshot-nameserver
According to AWS, 'a hosted zone tells Route 53 how to respond to DNS queries for a domain'. Let's first create a hosted zone on AWS Route 53.
Navigate to Route 53 in AWS console, and then to 'Hosted zones'.
Click on 'Create Hosted Zone', and enter the domain address you just purchased:
screenshot-createhostedzone
A hosted zone will be created:
screenshot-hostedzonecreated
Copy the 'values' listed for type 'NS' one by one to 'custom name servers' in Google Domains:
screenshot-copynameserver
Notice that changes made on Google Domains may take up to 48 hours to take effect.

Set up HTTPS for your domain

To set up HTTPS, we should get an SSL certificate on AWS and link it to the domain address.

  1. Go to AWS Certificate Manager to request an SSL certificate. Choose to 'request a public certificate', enter your domain name when prompted, select 'DNS validation' as validation method. Then follow
    screenshot-sslstep1
    screenshot-sslstep2
    Follow instructions and add CNAME record in Google Domains:
    screenshot-sslvalidation
  2. Link to Elastic Beanstalk.
    Go to your Elastic Beanstalk app, navigate to Configuration -> Load Balancer.
    screenshot-loadbalancer
    Edit the configuration of listeners for your load balancer. Choose 'HTTPS' and choose the SSL certificate you just received:
    screenshot-loadbalancerlistener