Skip to content

AWS Hosting — Deploy on EC2, S3 & Lightsail

DodaTech Updated 2026-06-20 9 min read

In this tutorial, you'll learn about AWS Hosting. We cover key concepts, practical examples, and best practices.

AWS hosting provides EC2 virtual servers, S3 static storage, and Lightsail managed VPS for deploying scalable web apps on the world's largest cloud platform.

In this tutorial, you will learn how to launch an EC2 Linux instance and host a web application, configure S3 for static website hosting with bucket policies, deploy on Lightsail for simplified VPS management, assign Elastic IPs, configure security groups, manage IAM roles, and integrate CloudFront CDN. DodaTech uses AWS to host Doda Browser update APIs and Durga Antivirus Pro signature databases.

What You'll Learn

By the end of this guide, you will deploy a web application on AWS using three approaches: EC2 for full control, S3 for static sites, and Lightsail for simplicity — each with proper security and networking.

Why AWS Hosting Matters

AWS hosts over 30% of the internet's cloud infrastructure. Understanding its core services — EC2, S3, and Lightsail — is essential for any developer deploying production applications at scale.

AWS Hosting Learning Path

flowchart LR
  A[EC2 Basics] --> B[Security Groups & IPs]
  B --> C[S3 Static Hosting]
  C --> D[Lightsail VPS]
  D --> E[CloudFront CDN]
  E --> F[IAM & Security]
  F --> G{You Are Here}
  style G fill:#f90,color:#fff

EC2 — Virtual Servers

Amazon S3 EC2 (Elastic Compute Cloud) provides resizable virtual machines in the cloud. You choose the operating system, CPU, memory, and storage.

Launch an EC2 Instance

# Using AWS CLI
aws ec2 run-instances \
  --image-id ami-0c55b159cbfafe1f0 \
  --instance-type t2.micro \
  --key-name my-key-pair \
  --security-group-ids sg-0123456789abcdef \
  --subnet-id subnet-0123456789abcdef \
  --user-data file://bootstrap.sh \
  --tag-specifications 'ResourceType=instance,Tags=[{Key=Name,Value=WebServer}]'

The --user-data parameter runs a script at launch. Example bootstrap.sh for a web server:

#!/bin/bash
# Install Apache on Amazon Linux 2023
dnf update -y
dnf install -y httpd
systemctl start httpd
systemctl enable httpd
echo "<h1>Welcome to AWS EC2</h1>" > /var/www/html/index.html

Expected output

aws ec2 describe-instances --instance-ids i-0123456789abcdef --query 'Reservations[0].Instances[0].State.Name'
# "running"

# Access the web server (replace with public IP)
curl http://54.123.45.67
# <h1>Welcome to AWS EC2</h1>

Instance Types

Family Use Case Example Cost
t2/t3 General purpose, burstable Web servers, dev/test Low (t2.micro ~$8/month)
c5/c6g Compute optimized CPU-heavy apps Medium
r5/r6g Memory optimized Databases, caching High
m5/m6g Balanced Production apps Medium

Security Groups

Security groups act as virtual firewalls controlling inbound and outbound traffic.

# Create a security group for web traffic
aws ec2 create-security-group \
  --group-name web-sg \
  --description "Allow HTTP, HTTPS, and SSH"

# Authorize inbound rules
aws ec2 authorize-security-group-ingress \
  --group-name web-sg \
  --protocol tcp --port 22 --cidr 203.0.113.0/24

aws ec2 authorize-security-group-ingress \
  --group-name web-sg \
  --protocol tcp --port 80 --cidr 0.0.0.0/0

aws ec2 authorize-security-group-ingress \
  --group-name web-sg \
  --protocol tcp --port 443 --cidr 0.0.0.0/0

Expected security group rules

Type Protocol Port Source Purpose
SSH TCP 22 203.0.113.0/24 Admin access only (not open to world)
HTTP TCP 80 0.0.0.0/0 Public web traffic
HTTPS TCP 443 0.0.0.0/0 Encrypted web traffic

Elastic IPs

By default, EC2 public IPs change on reboot. An Elastic IP provides a static address.

# Allocate an Elastic IP
aws ec2 allocate-address --domain vpc

# Associate with instance
aws ec2 associate-address \
  --instance-id i-0123456789abcdef \
  --allocation-id eipalloc-0123456789abcdef

Expected output

{
  "PublicIp": "203.0.113.42",
  "AssociationId": "eipassoc-0123456789abcdef"
}

S3 Static Website Hosting

Amazon S3 (Simple Storage Service) hosts static websites at global scale with 99.999999999% durability.

Create and Configure a Bucket

# Create bucket (name must be globally unique)
aws s3 mb s3://my-static-site-2026

# Enable static website hosting
aws s3 website s3://my-static-site-2026 \
  --index-document index.html \
  --error-document error.html

# Upload website files
aws s3 cp index.html s3://my-static-site-2026/
aws s3 cp error.html s3://my-static-site-2026/

# Make content publicly readable (requires bucket policy)

Bucket Policy for Public Access

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Sid": "PublicReadGetObject",
      "Effect": "Allow",
      "Principal": "*",
      "Action": "s3:GetObject",
      "Resource": "arn:aws:s3:::my-static-site-2026/*]
    }
  ]
}
aws s3api put-bucket-policy \
  --bucket my-static-site-2026 \
  --policy file://policy.json

Expected behavior

curl http://my-static-site-2026.s3-website-us-east-1.amazonaws.com
# <!DOCTYPE html><html>...Your static site content...</html>

Lightsail — Simplified VPS

Lightsail offers predictable pricing ($3.50-$120/month) with a simplified management console.

Launch a Lightsail Instance

# Create a Lightsail instance via AWS CLI
aws lightsail create-instances \
  --instance-names "MyWebApp" \
  --availability-zone us-east-1a \
  --blueprint-id "amazon_linux_2023" \
  --bundle-id "nano_2_0" \
  --user-data file://bootstrap.sh

Lightsail includes:

  • Fixed monthly pricing — no surprise bills
  • Built-in firewall — manage ports through the console
  • Static IP — one free static IP per instance
  • Snapshots — manual and automatic backups
  • Load balancer — add a balancer for $18/month

Connect and Verify

# View instance details
aws lightsail get-instance --instance-name "MyWebApp"

# Expected output snippet
{
  "instance": {
    "name": "MyWebApp",
    "state": "running",
    "publicIpAddress": "54.123.45.67",
    "blueprintName": "Amazon Linux 2023"
  }
}

CloudFront CDN

CloudFront distributes content globally across 450+ edge locations, reducing latency and offloading origin servers.

Create a CloudFront Distribution

aws cloudfront create-distribution \
  --origin-domain-name my-static-site-2026.s3.us-east-1.amazonaws.com \
  --default-root-object index.html \
  --enabled

Expected distribution details

Domain: d1234abcdef.cloudfront.net
Status: InProgress → Deployed (5-10 minutes)
Origins: 1 (S3 bucket)
Edge Locations: 450+ globally
Default TTL: 24 hours (86400 seconds)
# Test the CDN endpoint
curl -I https://d1234abcdef.cloudfront.net/index.html
# HTTP/2 200
# x-cache: Miss from cloudfront  (first request)
# curl -I https://d1234abcdef.cloudfront.net/index.html
# x-cache: Hit from cloudfront    (cached)

Common Errors

1. "Permission Denied" When SSH into EC2

Your key pair file has wrong permissions. Run chmod 400 my-key-pair.pem and retry. Also verify the security group allows inbound SSH from your IP address.

2. S3 Bucket Returns 403 Forbidden

The bucket policy does not grant public read access. Apply the policy shown in the S3 section above. Also ensure "Block all public access" is disabled in the bucket's Permissions tab.

3. EC2 Instance Terminated Immediately

The instance type is not available in the selected Availability Zone, or the AMI ID is incorrect. Use aws ec2 describe-instance-type-offerings to find available types in your region.

4. "You do not have permission to access the requested resource" in Lightsail

Your IAM user lacks Lightsail permissions. Attach the AmazonLightsailFullAccess policy in IAM. For production, create a scoped-down policy with only the actions needed.

5. CloudFront Distribution Stuck "InProgress"

Invalidations or origin configuration may cause delays. Check the distribution's Error Logs in CloudWatch. Verify the origin (S3 bucket or custom origin) is reachable and returns 200.

6. High AWS Bill Unexpectedly

A resource was left running (EC2 instance, Elastic IP not attached to instance, or S3 bucket with excessive data transfer). Use AWS Cost Explorer to identify the source. Set up billing alerts via CloudWatch.

7. "SignatureDoesNotMatch" Error in CLI

Your system clock is out of sync. Run sudo ntpdate -s time.nist.gov or install ntp to keep the clock accurate. AWS CLI requests include a timestamp that must be within 15 minutes of server time.

Practice Questions

1. What is the difference between EC2 and Lightsail?

EC2 offers granular control over instance types, networking, and pricing but requires more configuration. Lightsail provides simplified management with fixed monthly pricing and is ideal for beginners or predictable workloads.

2. How does S3 static website hosting differ from EC2 hosting?

S3 serves only static files (HTML, CSS, JS, images) with no server-side processing. EC2 can run any application (Node.js, Python, PHP) that requires server-side logic and a runtime environment.

3. What is an Elastic IP and why would you use it?

An Elastic IP is a static public IPv4 address that persists across instance stops and starts. Use it to maintain a consistent endpoint for DNS records even when the underlying instance changes.

4. How do security groups protect EC2 instances?

Security groups act as stateful firewalls. You define inbound rules (allowed IPs, ports, protocols) and outbound rules. Only traffic matching the rules is permitted. Changes apply immediately without restarting the instance.

5. Challenge: Deploy a full-stack app on AWS

Provision an EC2 instance with a Node.js API backend, an S3 bucket hosting a React frontend, and CloudFront in front of both. Configure the API's security group to allow traffic only from the CloudFront edge IPs.

Mini Project: Deploy a Web App on AWS

Set up a complete AWS hosting environment:

  1. Launch a t2.micro EC2 instance with Amazon Linux 2023 and a web server bootstrap script
  2. Create a security group allowing SSH (your IP only), HTTP, and HTTPS
  3. Allocate and associate an Elastic IP
  4. Create an S3 bucket with static website hosting enabled and a bucket policy for public read
  5. Upload a sample index.html and test via the S3 website endpoint
  6. Create a CloudFront distribution pointing to your S3 bucket
  7. Configure DNS in Route 53 to point your domain to CloudFront

Test each layer:

# Test EC2 instance
curl http://<elastic-ip>
# Expected: Web server response from EC2

# Test S3 static site
curl http://my-static-site-2026.s3-website-us-east-1.amazonaws.com
# Expected: Static HTML from S3

# Test CloudFront
curl -I https://d1234abcdef.cloudfront.net/index.html
# Expected: x-cache: Miss → Hit after second request

# Test security group
ssh -i my-key-pair.pem ec2-user@<elastic-ip>
# Expected: Connected (from allowed IP only)

This architecture powers Doda Browser download distribution and Durga Antivirus Pro signature update servers.

FAQ

How much does AWS hosting cost?

A t2.micro EC2 instance costs ~$8.50/month (750 hours free tier for 12 months). S3 static hosting costs pennies per GB. Lightsail starts at $3.50/month. Use the AWS Pricing Calculator for estimates.

Is AWS free tier enough for a production site?

The free tier (t2.micro, 5 GB S3, 1 million Lambda requests) works for low-traffic sites. For production traffic, upgrade to at least a t3.medium (~$30/month) and S3 Standard storage.

What is the difference between S3 and EC2 for hosting?

S3 serves static files only — no PHP, Python, or Node.js. EC2 runs full operating systems with any runtime. Use S3 for static sites and assets, EC2 for dynamic applications.

Can I host a WordPress site on AWS?

Yes. Launch an EC2 instance with the Amazon Linux or Ubuntu AMI, install Apache/Nginx, PHP, and MySQL (or use Amazon RDS). Lightsail offers one-click WordPress installation starting at $3.50/month.

How do I secure my AWS account?

Enable MFA on the root account, create IAM users with least-privilege policies, use IAM roles for EC2 instances (never store access keys on servers), enable CloudTrail for API logging, and set up billing alerts.

Built by the developers of Doda Browser, DodaZIP, and Durga Antivirus Pro.

Built by the developers of DodaTech

Doda Browser, DodaZIP & Durga Antivirus Pro