This walkthrough will show you how to deploy a containerized Node.js app to Amazon Web Services and also assign a secure custom domain. We will be applying the following technologies and tools:

  • Application: Node.js Express
  • Container: Docker and Github
  • Cloud Compute: AWS EC2 Ubuntu
  • Domain: AWS ElasticIP, AWS Route53 and Namecheap Domains
  • HTTPS: Nginx and Let’s Encrypt

1. Create Node App with Dockerfile and deploy to Github

Create a simple Node Express app with the following folder structure

Create a simple hello world web app.

Create Dockerfile which will install specific version of node, install dependencies, expose relevant port and run start command.

Test locally by building the Docker image (check Docker desktop app is running).

Test locally by running the app. Expose port 3000 (we will later use Nginx reverse proxy to send HTTPS port 80 requests to localhost:3000)

Commit and deploy to a Github repo where we will later clone from our EC2 Instance.

2. Create EC2 Instance

Create a new AWS EC2 Instance and set a fixed public IP.

  • Login to AWS Management Console
  • Select EC2 and select Launch Instance
  • Choose latest Ubuntu Server
  • Setup security groups including HTTP port 80 and HTTPSsecurity
  • Create instance and create name of private key and download (you will need this to ssh login to your cloud instance)
  • Create Elastic IP and associate to your instance. This will keep a fixed public IP address for your instanceelasticIP

3. SSH into EC2 Instance

Login to our newly created EC2 Instance via SSH.

  • Find and select your running EC2 instance and click Connect then follow the instructionsssh
  • Download your private key and run the following command to allow read ownership chmod 400 <YOUR_PRIVATE_KEY_NAME>.pem
  • If you forget your private key you will not be able to easily SSH back in
  • To asssist workflow create a folder named SSH in your local directory and include in .gitignore. You can keep your private key here and a textline of the SSH script. Then come back to this folder whenever you need to SSH in.

4. Setup and Install EC2 Dependencies

Clone github repo, install Docker, build image and run new image.

  • SSH into instance (follow instructions by clicking on “Connect” in the instance). See AWS console to find exact ssh command, ensure you are in the root directory with your private key
  • Once login successful, clone your github repo
  • Install Docker
  • Run Docker without sudo in ubuntu
  • Exit EC2 Instance and SSH back in and check you can run docker without sudo
  • Rebuild the Docker image (similar to what we did when testing locally)
  • Run the Docker image in detatched mode -d which will let it continue to run in the background. Set restart as always so it will run when the EC2 instance is restarted.
  • If you exposed port 3000 in the EC2 instance you should now be able to see the application if you visit the public DNS
  • To get the container id
  • To see container logs
  • To stop the container

5. Create Route 53

Setup AWS Route53 for DNS forwarding from our custom domain to relevant EC2 Instances.

  • Search for Route53 Service in AWS Management Console
  • Get started and create a hosted zone
  • Create the hosted zone and enter the domain name you wil purchase from namecheap
  • Once clicked you will see the NS records. Copy a record of thesens

6. Purchase Namecheap Domain

Purchase custom domain and point to AWS Route 53.

  • Purchase domain from namecheap and then set the Custom DNS to each of the NS records from Route53namecheap-dns
  • Connect your Route 53 to Namecheap. Copy the public “IPv4 Public IP” of your EC2 Instance. Hit create record set button and create 2 records below. One set name as empty while latter prefi with *. Copy into value the IPv4 Public IP address into reachrecordset

7. Setup Nginx and HTTPS

Nginx reverse proxy port 80 to our Docker instance and setup secure HTTPS.

  • SSH into EC2 Instance and setup nginx webserver
  • Install certbot and build certificate
  • Make the certificate with the given domain names you have purchased. It may prompt for email
  • Remove default config file
  • Create new file
  • Paste the following code in the file and replace example.com with your purchased domain and 3000 with your Node port
  • Symlink config file to sites-enabled
  • Restart nginx and apply
  • If nginx error due to port 80 already in use. Find, kill and restart nginx

That’s it.

You should now be able to visit your custom domain and be pointed to your Dockerized Node App on HTTPS.