Ravindra BagaleCourses & study guides Track your progress

Guides

How to Host a Static Website on Amazon S3 (Step by Step)

To host a static website on Amazon S3, create a bucket, upload index.html (and error.html), turn on Static website hosting in the bucket's Properties, turn off Block Public Access for that bucket only, and add a bucket policy that allows s3:GetObject for everyone. The site is then live at the bucket website endpoint, for example http://BUCKET.s3-website.ap-south-1.amazonaws.com. The S3 website endpoint is HTTP only; for HTTPS and a custom domain, put CloudFront in front.

Come on, friends! We hosted a website on EC2 with Nginx – the server, updates, security group, all on our own head. Today, a different trick: a website without a server. If you have HTML, CSS and images, create a bucket on Amazon S3, put the files in, and the site is live. Today we put my small shayari site on S3. Pay attention: this is the only bucket we make public on purpose.

Quick answer

With the AWS CLI configured (the console steps are below):

BUCKET=tujanena-shayari-site-2026            # globally unique, lowercase
aws s3 mb s3://$BUCKET --region ap-south-1
aws s3 sync ./site s3://$BUCKET/             # index.html, error.html, css/, img/
aws s3 website s3://$BUCKET/ --index-document index.html --error-document error.html
aws s3api put-public-access-block --bucket $BUCKET --public-access-block-configuration \
  BlockPublicAcls=true,IgnorePublicAcls=true,BlockPublicPolicy=false,RestrictPublicBuckets=false
aws s3api put-bucket-policy --bucket $BUCKET --policy file://policy.json   # public read, Step 5
# open http://tujanena-shayari-site-2026.s3-website.ap-south-1.amazonaws.com

What do I need before hosting a site on S3?

How does an S3 website answer a browser?

How an S3 static website answers a browser The browser requests the site from the S3 website endpoint over HTTP. Block Public Access is off for this bucket only and the bucket policy allows s3:GetObject, so S3 returns index.html and the page appears. No web server is involved. Shayari ✓ Browser http:// only GET / (website endpoint) index.html S3 bucket tujanena-shayari-site Block Public Access: off policy: s3:GetObject index.html error.html GET /200 OK

The browser asks the S3 website endpoint for a page. Block Public Access is off for this bucket only, the bucket policy allows s3:GetObject, so S3 returns index.html over HTTP. No server to manage.

How do I host a static website on Amazon S3?

Step 1 — Prepare the files

For practice, make a tiny two-page site on your laptop:

mkdir site && cd site
cat > index.html <<'HTML'
<!DOCTYPE html>
<html lang="mr"><head><meta charset="utf-8"><meta name="viewport" content="width=device-width, initial-scale=1">
<title>Shayari</title></head>
<body style="font-family:sans-serif;text-align:center;padding-top:60px">
  <h1>आजची शायरी</h1><p>Hosted on Amazon S3 – no server!</p>
</body></html>
HTML
echo '<h1>404 – page not found</h1><a href="/">Home</a>' > error.html
cd ..

Keep <meta charset="utf-8"> in every page so Marathi and Hindi text shows correctly.

Step 2 — Create the bucket

S3 → Create bucket → General purpose → a bucket name such as tujanena-shayari-site-2026. Bucket names are global across all AWS accounts, lowercase, 3–63 characters, no spaces or underscores. Choose your region (for example Asia Pacific (Mumbai) ap-south-1). Keep Object Ownership: ACLs disabled.

Step 3 — Allow public policies for this bucket only

In Block Public Access settings for this bucket, untick Block all public access and tick the acknowledgement. Then Create bucket. If the bucket already exists: Permissions → Block public access (bucket settings) → Edit.

Leave the account-level Block Public Access and all your other buckets untouched.

Ravindra Bagale's Tip

Many students accidentally upload the .git folder, .env or backup.zip into the website bucket too – and those become public as well! Upload with aws s3 sync ./site s3://bucket/ --exclude ".git/*" --exclude "*.env" --exclude "*.zip", and afterwards check once with aws s3 ls s3://bucket --recursive exactly what has become public. This bucket holds only the website, nothing else.

Step 4 — Upload the files

Open the bucket → Upload → Add files (index.html, error.html) and Add folder (css/, img/ if you have them) → Upload. index.html must sit at the root of the bucket, not inside a site/ folder.

Step 5 — Add the public read bucket policy

Permissions → Bucket policy → Edit, paste this (change the bucket name) and Save changes:

{
  "Version": "2012-10-17",
  "Statement": [{
    "Sid": "PublicReadWebsite",
    "Effect": "Allow",
    "Principal": "*",
    "Action": "s3:GetObject",
    "Resource": "arn:aws:s3:::tujanena-shayari-site-2026/*"
  }]
}

Only s3:GetObject — never s3:ListBucket or s3:PutObject for "Principal": "*". The /* at the end of Resource means "every object in the bucket".

Step 6 — Turn on static website hosting

Properties → scroll to Static website hosting → Edit → Enable → Host a static website → Index document index.html, Error document error.html → Save changes. The same section now shows the Bucket website endpoint:

http://tujanena-shayari-site-2026.s3-website.ap-south-1.amazonaws.com

Open it on your phone — your site is live, with no server to patch. 🎉 Try a wrong path such as /abc to see error.html.

Step 7 — Update the site later

aws s3 sync ./site s3://tujanena-shayari-site-2026/ --delete --exclude ".git/*"

--delete removes files from the bucket that you deleted locally. Browsers may cache old files for a short time; refresh with Ctrl+F5.

Ravindra Bagale's Tip

Pay attention: when you open a file in the bucket you see an object URL like https://bucket.s3.ap-south-1.amazonaws.com/index.html – that is not the website endpoint. The website endpoint contains the word s3-website, and it works only on http://. The browser adds https:// and students say the site doesn't work. Got it? If you need HTTPS, use CloudFront.

Step 8 — HTTPS and your own domain (next step)

For a real site, create a CloudFront distribution with the bucket as origin and Origin Access Control (OAC), so only CloudFront can read the bucket and Block Public Access can stay on. Add a free certificate from AWS Certificate Manager (in us-east-1 for CloudFront) and point www.yourdomain.com to CloudFront with a CNAME record.

Option HTTPS Bucket public? Use for
S3 website endpoint (this guide) No Yes, read only Learning, quick demos
CloudFront + OAC Yes, custom domain No Real production static sites
Nginx on EC2 Yes, with Certbot Not applicable When you also need server-side code

How do I fix common S3 website errors?

Ghabru naka 😅 — these are the usual ones:

Symptom Likely cause Fix
403 Forbidden (Access Denied) No bucket policy, Block Public Access still on, or Resource without /* Step 3 and Step 5; check the bucket name in the ARN
Access denied when saving the policy Block Public Access still blocks public policies Untick it for this bucket (Step 3), then save the policy again
404 Not Found / NoSuchKey index.html not at the root, or wrong name (Index.html) Move it to the root; names are case-sensitive
Page downloads instead of opening Wrong Content-Type from a manual upload Upload again with the console or aws s3 sync (sets text/html)
Site does not open with https:// The website endpoint is HTTP only Use http://, or CloudFront for HTTPS
BucketAlreadyExists The name is taken in another account Pick another unique name
Marathi text shows as strange symbols Missing charset Add <meta charset="utf-​8"> to the page and upload again

Learn it properly

This guide is the short path. The free Cyber Security course explains S3 security in depth, with labs:

Samajla ka? Got it? Bucket, upload, Block Public Access off for this bucket only, the GetObject policy, and static website hosting on – a website without a server is ready. Next, let's learn CloudFront for HTTPS and a domain.

Frequently asked questions

How do I host a static website on S3?

Create a bucket, upload index.html, enable Static website hosting in the bucket properties, turn off Block Public Access for that bucket, and add a bucket policy that allows s3:GetObject for everyone.

Why do I get 403 Forbidden on my S3 website?

The bucket policy is missing or wrong, Block Public Access is still on, or index.html is not at the bucket root. The policy Resource must end with /*.

Does S3 static website hosting support HTTPS?

No. The S3 website endpoint is HTTP only. For HTTPS and your own domain, put Amazon CloudFront in front of the bucket.

Can S3 host a PHP or WordPress website?

No. S3 serves only static files (HTML, CSS, JavaScript, images). For PHP, WordPress or a database, use EC2 or another compute service.

Is it safe to make an S3 bucket public?

Only for a bucket that holds nothing but the public website files, and only with s3:GetObject. Never allow s3:ListBucket or s3:PutObject to everyone, and keep Block Public Access on for every other bucket.

Should I host a static site on S3 or on EC2 with Nginx?

S3 needs no server, no patching and scales by itself, so it is ideal for simple sites. EC2 with Nginx teaches Linux and web server skills and can later run server-side code.