Part 1: Deploying a Secure Full-Stack Application on AWS EC2 with Docker and Nginx

Part 1: Deploying a Secure Full-Stack Application on AWS EC2 with Docker and Nginx

ยท

8 min read

Deploying a full-stack application could be overwhelming. In this regard, it involves many steps and configurations to achieve seamless functioning. Setting up a stable and secure environment requires meticulous planning and execution. This section will walk you through how to set up such an environment, including the essential steps: launching an EC2 Instance, setting security settings, automating scripts and connecting to an EC2 instance.

Setting up the proper environment is vital to stable and secure deployment processes. The tools we recommend, such as AWS EC2, Docker, and automated scripts, are designed to make your job easier. They streamline the setup process, reduce potential errors, and enhance security measures. Following our step-by-step guide, you can quickly deploy a full-stack Application, confident in the robust and efficient setup you've created for your Application.

Prerequisites

Before you begin, make sure you have the following:

  • AWS account: You will need this to create and manage your EC2 instances.

  • Domain Name: Used to route traffic to your Application.

  • Docker: A basic understanding of Docker and Docker Compose for managing your application containers.

  • Nginx: Familiarity with Nginx is necessary to set up your web server.

  • Linux command line: command-line instructions to configure your environment and deploy your Application.

Step 1: Setting Up the EC2 Instance

Launching an EC2 Instance

Log in to your AWS account and search for EC2. Click on it and select the launch instance button to start setting up an instance configuration. Follow the instructions below to ensure your instance is configured correctly for your deployment.

  1. Select the Ubuntu 22.04 LTS AMI:

    • Give your EC2 a name of your choice, but I am naming mine Techdoc-backend.

    • Choose "Ubuntu" under Server 22.04 LTS from the list of available AMIs and ensure it is "Canonical, Ubuntu, 24.04 LTS, amd64 noble image build." Every other setting remains the default.

  2. Choose the Instance Type and set the Key Pair:

    • Since our Application contains a database and other configurations, we will select the t3.small instance type to ensure enough CPU and Memory are available for our workloads.

    • You need to create a new key pair to connect to your EC2 via the CLI. It's important because you might want to transfer files from your local machine to your EC2 servers. Create and download the key pair.

Configuring Network settings

To ensure the Application properly connects to our EC2, it is essential to set up the necessary inbound rules by enabling the port used by our Applications and configuring the database port.

  1. Setting Up Inbound Rules:

    • Select the Edit button in the Network section, scroll down, and select "Add Security group rule."

    • In the Inbound Security Group Rules section, For Type, select HTTP; for Source, select "Anywhere" This allows HTTP traffic to our EC2. Repeat these steps for the following ports below.

    • SSH: Port 22, Source: Anywhere (0.0.0.0/0) - This allows SSH access.

    • HTTP: Port 80, Source: Anywhere (0.0.0.0/0) - This allows HTTP traffic.

    • HTTPS: Port 443, Source: Anywhere (0.0.0.0/0) - This allows HTTPS traffic.

    • Custom TCP: Port 8000, Source: Anywhere(0.0.0.0/0) - Our Application uses this port to connect to our Express.js server. Configure yours and use your port for your Application.

    • Custom TCP: Port 27017, Source: Anywhere(0.0.0.0/0) - This port allows us to connect to MongoDB in the EC2 instance because we need remote access. If Your MongoDB runs on another server, you may not need this port open.

    • Custom TCP: Port 3000, Source: Anywhere(0.0.0.0/0) - This allow us to connect t our frontend Application. If you do not need this port for production, you can leave it closed.

  2. Configure the storage:

    • Change from 8 to 30 to ensure our Application has enough storage to install the necessary software from our user script, which we will configure next.

Step 2: Configuring the Instance with a User Data Script

Using User Data Script

User data scripts are bash scripts that are powerful tools for automating the setup of your EC2 instance upon launch. They can install software, configure services, and set up your environment without manual intervention.

Script to Automate Installation and Configuration:

To configure your instance with a user data script, follow these steps:

  1. Click on the "Advanced Details":

    • Scroll down to the "User Data" section.

    • Under "Metadata version," select "V1 and V2 (token optional)".

  2. Copy and paste the bash script below into the User Data section:

     #!/bin/bash
    
     # Update the package index
     sudo apt update -y
     sudo apt upgrade -y
    
     # Install Docker
     sudo apt install docker.io -y
     sudo systemctl start docker
     sudo systemctl enable docker
     sudo usermod -aG docker ubuntu
    
     # Install Docker Compose
     sudo curl -L "https://github.com/docker/compose/releases/download/1.29.2/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
     sudo chmod +x /usr/local/bin/docker-compose
    
     # Install Git
     sudo apt install git -y
    
     # Install Nginx
     sudo apt install nginx -y
     sudo systemctl start nginx
     sudo systemctl enable nginx
    
     # Install Certbot
     sudo apt install certbot python3-certbot-nginx -y
    
     # Create Docker network
     sudo docker network create app-network
    
     # Create the project directory
     # Change to your own folder directory [techdoc-backend]
     mkdir -p /home/ubuntu/techdoc-backend
    
     # Change ownership of the project directory to ubuntu
     sudo chown ubuntu:ubuntu /home/ubuntu/techdoc-backend
    
     # Clone the repository into the project directory as ubuntu
     # Please Change to your own github repo link
     sudo -u ubuntu git clone https://github.com/lokytech5/techdoc-backend.git /home/ubuntu/techdoc-backend
    
     # Navigate to the project directory
     cd /home/ubuntu/techdoc-backend
    
     # Ensure correct permissions for the project directory
     sudo chown -R ubuntu:ubuntu /home/ubuntu/techdoc-backend
    
     # Create the .env file in the project directory
     # Add Application environment variable
     cat <<EOF > /home/ubuntu/techdoc-backend/.env
     MONGO_URI=mongodb://root:example@tutihair_db:27017/tutiEcommerceDB?authSource=admin
     # MONGO_LOCAL_DB_SETUP=mongodb://127.0.0.1:27017/tutiEcommerceDB
     EOF
    
     # Ensure correct permissions and ownership for the .env file
     sudo chown ubuntu:ubuntu /home/ubuntu/techdoc-backend/.env
    
     # Start the Docker Compose services
     sudo -u ubuntu docker-compose -f /home/ubuntu/techdoc-backend/docker-compose.yml up -d
    
     # Print completion message
     echo "Docker installation complete, and Application started"
    
     # Prompt user to log out and log back in for Docker group membership to take effect
     echo "Please log out and log back in for Docker group membership to take effect."
    
     # Set up Certbot (It can't be automated becasue it requires user interaction)
     # You must manually complete this step after the instance is up
     echo "Run 'sudo certbot --nginx' to set up SSL after the instance is running."
    

    Explanation:

    • sudo apt update -y: Updates the package list to get the latest versions of packages and their dependencies.

    • sudo apt upgrade -y: Upgrades all the installed packages to their latest versions.

    • sudo apt install docker.io -y: To install Docker.

    • sudo systemctl start docker: Starts the Docker service.

    • sudo systemctl enable docker: Enables Docker to start on boot.

    • sudo usermod -aG docker ubuntu: Adds the ubuntu user to the Docker group.

    • sudo curl -L "[https://github.com/docker/compose/releases/download/1.29.2/docker-compose-$(uname](github.com/docker/compose/releases/download.. -s)-$(uname -m)" -o /usr/local/bin/docker-compose: To Download Docker Compose.

    • sudo chmod +x /usr/local/bin/docker-compose: Makes Docker Compose executable.

    • sudo apt install git -y: Installs Git for cloning the repository.

    • sudo apt install nginx -y: Installs Nginx.

    • sudo systemctl start nginx: Starts the Nginx service.

    • sudo systemctl enable nginx: Enables Nginx to start on boot.

    • sudo apt install certbot python3-certbot-nginx -y: Installs Certbot for SSL certificates.

    • sudo docker network create app-network: Creates a Docker network named app-network.

    • mkdir -p /home/ubuntu/techdoc-backend: Creates the project directory.

    • sudo chown ubuntu:ubuntu /home/ubuntu/techdoc-backend: Changes the ownership of the directory to the ubuntu user.

    • sudo -u ubuntu git clone https://github.com/lokytech5/techdoc-backend.git /home/ubuntu/techdoc-backend: Clones the repository into the project directory as the ubuntu user.

    • cat <<EOF > /home/ubuntu/techdoc-backend/.env ... EOF: Creates the .env file containing the essential environment variables for

    • sudo chown ubuntu:ubuntu /home/ubuntu/techdoc-backend/.env: Ensures the .env file has the correct permissions and ownership.

    • sudo -u ubuntu docker-compose -f /home/ubuntu/techdoc-backend/docker-compose.yml up -d: Starts the Docker Compose services.

    • echo "Docker installation complete, and application started": Prints a completion message.

    • echo "Please log out and log back in for Docker group membership to take effect.": Prompts the user to log out and back in for Docker group membership to take effect.

    • echo "Run 'sudo certbot --nginx' to set up SSL after the instance is running.": Instruct the user to complete the SSL setup with Certbot manually.

Step 3: Connecting to the EC2 Instance

Connecting to an EC2 instance is using the instance key you downloaded earlier and installing the AWS CLI on your local machine or via the AWS console. We will use the AWS console, which is quick and easy.

Connecting to the EC2 Instance

  • Using the AWS Console:

    • Navigate to the EC2 Dashboard.

    • Select the instance you launched.

    • Click on the "Connect" button.

    • Choose the "EC2 Instance Connect" option and click "Connect".

  • Verifying the Setup:

    • Verify Docker, Docker Compose Installation and Check Nginx Status:

      • Once connected, run the following command to check if Docker and Docker Compose are installed and running. Use the command below to confirm if our Nginx is working as expected.

          docker --version
          docker-compose --version
          sudo systemctl status nginx
        

Conclusion

In this part, we have explored the essential steps to set up your environment for full-stack deployment. By automating the installation and configuration process with a user data script, we ensure reproducibility and efficiency, making your deployment process smoother and more reliable.

By setting up a secure EC2 instance and configuring it with the necessary software and services, you lay a strong foundation for your deployment. Automation saves time and reduces human error, creating a more robust and consistent deployment environment.

ย