Skip to main content
This guide demonstrates how to host a simple static website on Amazon S3. It walks through the project layout, uploading files, enabling static website hosting, adjusting permissions, and confirming the website endpoint. Use the steps below to quickly publish a static site using an S3 bucket (example bucket used here: kk-static-demo).

Project structure and files

Project files for this demo: index.html
404.html (error page)
When a visitor opens the bucket website root (the bucket website endpoint without a specific object), S3 serves the index document (index.html). That page, in turn, loads index.css and images from the images/ folder.

Create the S3 bucket

  1. Open the Amazon S3 console and create a new bucket. In this demo the bucket name was kk-static-demo. Leave other settings as default for a simple test deployment.
A screenshot of the Amazon S3 console showing the "Create bucket" page with fields for bucket name (example "myawsbucket"), AWS region (US East N. Virginia), and object ownership/ACL settings. The page displays general configuration and options for copying settings from an existing bucket.

Upload your website files

  • Upload index.html, index.css, 404.html, and the images/ folder to the bucket. Upload duration depends on image sizes.
A screenshot of the AWS S3 console showing an "Upload succeeded" banner and an upload status page. The summary shows 13 files (2.5 MB) uploaded to the s3://kk-static-demo bucket and a list of image files with "Succeeded" status.

Enable static website hosting

  1. Go to the bucket’s Properties tab.
  2. Find Static website hosting and click Edit (or Enable).
  3. Choose Host a static website and set:
    • Index document: index.html
    • Error document: 404.html
  4. Save the settings.
The “Index document” defines the default object S3 returns when no specific object is requested (site root). The “Error document” is returned when a requested object is missing.
You can preview the 404 page locally to ensure it looks correct.
A screenshot of a minimal webpage showing a large "404" error with the text "Page not found" centered on a white background. The browser's address bar at the top indicates a local file path.
The static website hosting pane confirms the index document setting and shows your files for reference.
A screenshot showing the AWS S3 console static website hosting settings on the left and a Windows File Explorer window on the right containing a "static-demo" folder with files like index.html, index.css, 404.html and an images folder. The console highlights the index document set to index.html.

Initial “Access Denied” and required permissions

  • After enabling website hosting, visiting the site endpoint may return “Access Denied” if your objects are not publicly retrievable. S3 static website hosting requires that objects be readable by the principal you intend (commonly anonymous public read for public websites).
Example AccessDenied response you might see in the browser:

Make the bucket objects retrievable (public read)

  1. In the bucket Permissions tab → Block public access, click Edit. To apply a public bucket policy you must first disable the block that prevents public policies from being added.
A screenshot of the Amazon S3 console showing the "Edit Block public access (bucket settings)" page. It lists several checkbox options to block public access (ACLs, bucket policies, cross-account) with a "Save changes" button.
  1. Confirm the change when prompted. The console warns that this may make objects public; you must type confirm and proceed.
A screenshot of the AWS S3 console showing an "Edit Block public access (bucket settings)" confirmation dialog. It warns that changing block public access may make objects public and asks the user to type "confirm" before clicking the orange Confirm button.
  1. Add a bucket policy that allows public read (s3:GetObject) to objects. Replace kk-static-demo with your bucket name:
  • This policy grants anonymous users read access to GET objects in the bucket. It does not grant deletion, write, or other privileged permissions.
If your bucket’s Object Ownership is set to “Bucket owner enforced” (which disables ACLs), granting public read via ACLs won’t work — use a bucket policy (like the example above) to allow GetObject. Conversely, if you rely on ACLs, ensure ACLs are enabled and not blocked by the Block Public Access settings.
After applying the policy and disabling blocking rules, the S3 console should indicate the bucket is “publicly accessible” for read operations.

Confirming the website endpoint

  • Open the bucket Properties → Static website hosting and click the site endpoint.
  • Visiting the root URL (no object specified) returns index.html automatically — you don’t need to append /index.html.
  • You can fetch specific objects directly, for example:
    • https://<bucket-website-endpoint>/images/food1.jpg
  • Requesting a non-existent object returns your configured error document (404.html) and displays your custom 404 page.
Amazon S3 static website endpoints serve content over HTTP only (no HTTPS). If you need HTTPS, place a CDN such as Amazon CloudFront in front of the bucket and configure an origin access control (OAC) or origin access identity (OAI) so you can keep the bucket private while serving content securely over HTTPS.

Quick reference: common settings

This workflow is suitable for simple static sites and demos. For production sites, consider using CloudFront with HTTPS, proper caching, and security controls (OAC/OAI, least-privilege policies, logging, and monitoring).

Watch Video