💻

Deploying a Node Application on AWS EC2

Jul 11, 2024

Deploying a Node Application on AWS EC2

Introduction

  • Objective: Take a web application running locally and host it on the internet using AWS EC2.
  • Technologies used: Node.js, PostgreSQL, AWS EC2, caddy for reverse proxy, and systemd for process management.

Setting Up the EC2 Instance

Launching an EC2 Instance

  1. Open AWS Console:
    • Navigate to EC2 and select 'Launch Instance'.
  2. Instance Configuration:
    • Name: "my web app".
    • Base Image: Ubuntu (latest version, 64-bit x86).
    • Instance Type: T2 micro (free tier eligible).
  3. SSH Access:
    • Create a new key pair (e.g., "California-Sam-MacBook-Pro").
    • Download and move the key pair to ~/.ssh/ directory.
  4. Network Settings:
    • Configure firewall rules to allow SSH from your IP address.
    • Allow HTTP and HTTPS traffic from anywhere.
    • Name the security group "my web app Security Group".
  5. Storage:
    • Default settings are usually sufficient.
  6. Launch Instance.

Connecting to the EC2 Instance

SSH into the Instance

  1. Access Instructions:
    • Click 'Connect' on the instance and follow the SSH instructions.
  2. SSH Command:
    • Use the downloaded key pair to SSH into the instance: ssh -i "path-to-key" ubuntu@your-ec2-instance-public-ip
  3. Permissions:
    • Ensure the key file has the correct permissions: chmod 400 your-key.pem.

Configuring the EC2 Instance

Update and Upgrade Packages

  1. Command: sudo apt update sudo apt upgrade
  2. Select All Applications to be restarted if prompted.

Installing Node.js

  1. Install Node.js: sudo apt install nodejs sudo apt install npm
  2. Verify Installation: node -v npm -v

Deploying Application Code

Uploading Code to EC2

  1. Use rsync Command:
    • Transfer code from local machine to EC2 instance.
    rsync -avz -e "ssh -i path-to-key" --exclude 'node_modules' --exclude '.git' ./ ubuntu@your-ec2-instance-public-ip:/home/ubuntu/app

Running the Node Application

  1. Navigate to App Directory: cd ~/app
  2. Install Dependencies: npm install
  3. Build the Project (if using TypeScript): npm run build
  4. Start the Application: npm start

Configuring PostgreSQL

Installing PostgreSQL

  1. Install PostgreSQL: sudo apt install postgresql postgresql-contrib
  2. Start PostgreSQL: sudo systemctl start postgresql sudo systemctl enable postgresql
  3. Create Database and User:
    • Access PostgreSQL shell: sudo -u postgres psql
    • Create database and user with privileges: CREATE DATABASE myapp; CREATE USER myappuser WITH ENCRYPTED PASSWORD 'password'; GRANT ALL PRIVILEGES ON DATABASE myapp TO myappuser;
  4. Run Migrations: npm run migrate

Running Application in Background

Using systemd

  1. Create Environment File:
    • Location: /etc/environment.d/myapp.env
    • Add environment variables (e.g., DATABASE_URL).
  2. Set Permissions: chmod 600 /etc/environment.d/myapp.env
  3. Create systemd Service File:
    • Location: /etc/systemd/system/myapp.service
    • Content: [Unit] Description=My Web App After=network.target [Service] User=ubuntu WorkingDirectory=/home/ubuntu/app ExecStart=/usr/bin/npm start EnvironmentFile=/etc/environment.d/myapp.env Restart=always StandardOutput=syslog StandardError=syslog SyslogIdentifier=myapp [Install] WantedBy=multi-user.target
  4. Start and Enable Service: sudo systemctl daemon-reload sudo systemctl start myapp.service sudo systemctl enable myapp.service
  5. Verify Service Status: sudo systemctl status myapp.service

Adding Custom Domain and SSL

Configure Custom Domain on Route 53

  1. Create Hosted Zone and add a record:
    • Record Type: A.
    • Name: Subdomain (e.g., "expenses.smw.wtf").
    • Value: EC2 instance's public IP.
    • Routing Policy: Simple.

Installing and Configuring Caddy for SSL

  1. Install Caddy: sudo apt install -y debian-keyring debian-archive-keyring apt-transport-https curl -1sLf 'https://dl.cloudsmith.io/public/caddy/stable/gpg.key' | sudo tee /etc/apt/trusted.gpg.d/caddy-stable.asc curl -1sLf 'https://dl.cloudsmith.io/public/caddy/stable/debian.deb.txt' | sudo tee /etc/apt/sources.list.d/caddy-stable.list sudo apt update sudo apt install caddy
  2. Modify Caddyfile:
    • Location: /etc/caddy/Caddyfile
    • Content: expenses.smw.wtf { reverse_proxy 127.0.0.1:3000 }
  3. Restart Caddy: sudo systemctl restart caddy
  4. Access Application: Visit the configured domain expenses.smw.wtf in a browser.
    • Ensure https redirection works automatically.

Conclusion

  • This setup is suitable for learning and small-scale apps.
  • For large-scale apps, additional configurations for scaling, load balancing, and database management are required.