Using S3 for Static Web Hosting

DZone 's Guide to

Using S3 for Static Web Hosting

Assuming you use the right language(s), you can set up your static website using AWS' S3.

· Cloud Zone ·
Free Resource

Hosting a static website is possible with S3, an AWS service that offers unlimited cloud storage capacity. You are able to deliver static content like HTML, CSS, images (e.g., PNG and JPG), audio, or videos. You can't execute server-side scripts like PHP or JSP, but it is, of course, possible to deliver client-side scripts (e.g., JavaScript) from S3.

This article is an excerpt from our book Amazon Web Services in Action.

In addition to that, S3 offers the following features for hosting a static website:

  • Define a custom index document and error documents.
  • Define redirects for all or specific requests.
  • Setting up a custom domain for S3 buckets.

Creating a Bucket for Static Web Hosting

To create a new S3 bucket, please open your command line and execute the following command. You'll have to replace $BucketName with your own bucket name. The bucket name has to be globally unique, so it is a good idea to use your own domain name as bucket name — like static.yourdomain.com. If you want to redirect your own domain name to S3, it is mandatory to use your whole domain name as bucket name.

$ aws s3 mb s3://$BucketName

Your bucket is empty, so you will place an HTML document into your bucket next. We prepared a placeholder HTML file. Download it to your local machine from here.

You are now able to upload the file to S3. Execute the following command to do so and replace $PathToPlacerholder with the path to the HTML file you downloaded in the previous step and $BucketName with the name of your bucket.

$ aws s3 cp $PathToPlaceholder/helloworld.html s3://$BucketName/helloworld.html                 

You created a bucket and uploaded an HTML document called helloworld.html. You will need to configure the bucket next.

Configuring a Bucket for Static Web Hosting

By default, only you, the owner, can access files from your S3 bucket. Since you want to use S3 to deliver your static website, you'll need to allow everyone to view or download the documents included in your bucket. A bucket policy will help you control access to objects of a bucket globally. An IAM policy is defined in JSON and contains one or more statements. A statement can either allow or deny specific actions on specific resources. A bucket policy is the same as an IAM policy.

Please download our bucket policy. You can run the following command to download the file directly from your command line if you are working with OS X or Linux or have installed wget on Windows.

$ wget https://raw.githubusercontent.com/AWSinAction/code/master/chapter7/bucketpolicy.json 

You have to edit the bucketpolicy.json file next. Open the file with the editor of your choice and replace $BucketName with the name of your bucket.

      "Principal": "*",

Adding a bucket policy to your bucket can be done with the following command. Please replace the $BucketName with the name of your bucket and $PathToPolicy with the path to the bucketpolicy.json file.

$ aws s3api put-bucket-policy --bucket $BucketName --policy file://$PathToPolicy/bucketpolicy.json

Every object of your bucket can be downloaded from everybody now. You will need to enable and configure the static web hosting feature of S3 next. To do this, execute the following command. Please replace the $BucketName with the name of your bucket.

$ aws s3 website s3://$BucketName --index-document helloworld.html

Your bucket is now configured to deliver your static website. The HTML document helloworld.html is used as an index page. You will learn how to access your website next.

Accessing Your Website Hosted on S3

You are able to access your static website with your browser now. To do so, you need to choose the right endpoint. The endpoints for S3 static web hosting depend on the region of your bucket.


Your bucket was created in the default region us-east-1. So you just need to enter the $BucketName to put together the endpoint for your bucket and replace $Region with us-east-1.


Open this URL, and you should be welcomed with a Hello World website.

Don't forget to clean up your bucket after you finished the example. To do so, execute the following command and replace the $BucketName with the name of your bucket.

$ aws s3 rb --force s3://$BucketName

Increasing Speed With a CDN

The use of a content delivery network (CDN) will help you to reduce the load time for static web content. A CDN distributes static content like HTML, CSS, or images to servers all around the world. If a user sends out a request for some static content the CDN will serve that request from the nearest available server with the lowest latency.

Amazon S3 is not a CDN, but you can easily use S3 as the backend for the CDN services of AWS called Amazon CloudFront. Please have a look at the CloudFront documentation if you want to set this up, as we will not cover it in this article.

Linking a Custom Domain to an S3 Bucket

If you want to avoid hosting your static content under a domain like awsinaction.s3-website-us-east-1.amazonaws.com you are able to link a custom domain to an S3 bucket. All you have to do is to add a CNAME record for your domain pointing to the S3 endpoint of your bucket.

The CNAME record will only work if you comply with the following requirements:

  • Your bucket name has to match with the CNAME record name. So if you want to create a CNAME for static.yourdomain.com your bucket name has to be static.yourdomain.com as well.
  • CNAME records will not work for the primary domain name. You need to use a sub-domain for CNAMEs like static or www, for example. If you want to link a primary domain name to an S3 bucket you need to use the DNS services from AWS called Route 53.


Is anything missing? Looking forward to your feedback! @andreaswittig or andreas@widdix.de.

amazon s3, static

Published at DZone with permission of Andreas Wittig . See the original article here.

Opinions expressed by DZone contributors are their own.

{{ parent.title || parent.header.title}}

{{ parent.tldr }}

{{ parent.urlSource.name }}