AWS Hosting — Deploy on EC2, S3 & Lightsail
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:
- Launch a t2.micro EC2 instance with Amazon Linux 2023 and a web server bootstrap script
- Create a security group allowing SSH (your IP only), HTTP, and HTTPS
- Allocate and associate an Elastic IP
- Create an S3 bucket with static website hosting enabled and a bucket policy for public read
- Upload a sample
index.htmland test via the S3 website endpoint - Create a CloudFront distribution pointing to your S3 bucket
- 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
Built by the developers of Doda Browser, DodaZIP, and Durga Antivirus Pro.
Built by the developers of DodaTech
Doda Browser, DodaZIP & Durga Antivirus Pro