logo

How To Host Static Websites On Amazon AWS S3

In this tutorial we are deploying a static website to Amazon AWS S3. Suppose your host name is test.example.com

Local Box

Install CLI

On Mac:

$ brew install awscli

On Ubuntu/Debian:

$ sudo apt install awscli

Configure

$ aws configure
AWS Access Key ID [None]: AKIAIOSFODNN7EXAMPLE
AWS Secret Access Key [None]: wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY
Default region name [None]: us-west-2
Default output format [None]: json

Sync

$ aws s3 sync . s3://my-bucket

Note that if you delete some local files, this will not delete the corresponding remote files in the bucket. To delete those, add --delete

$ aws s3 sync --delete . s3://my-bucket

If you regenerate local files using some static site generator like Jekyll or Hexo, the newly generated files will have different timestamp, so by default everything will be uploaded. To decide whether to upload a file by its size instead, use --size-only

$ aws s3 sync --delete --size-only . s3://my-bucket

To find more options, call help

$ aws s3 sync help

Amazon AWS S3 Console

Go to console: https://console.aws.amazon.com/s3

Create Bucket

Click Create Bucket, fill in Bucket Name.

Note: if you are not using Route 53, make sure you use the exact domain name as the bucket name, e.g. test.example.com, otherwise you will see the follow error:

404 Not Found

- Code: NoSuchBucket
- Message: The specified bucket does not exist
- BucketName: test.example.com
- RequestId: ......
- HostId: ......

Enable Website Hosting

Modify bucket properties, Static Website Hosting section, click Enable website hosting, add Index Document, e.g. index.html, save.

Add Bucket Policy

Click Add bucket policy, add this to the text area, make sure to change the bucket name in Resource:

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Sid": "PublicReadForGetBucketObjects",
      "Effect": "Allow",
      "Principal": "*",
      "Action": "s3:GetObject",
      "Resource": "arn:aws:s3:::test.example.com/*"
    }
  ]
}

DNS

Add a CNAME record:

NAME    TYPE    DATA
test    CNAME   test.example.com.s3-website-us-west-2.amazonaws.com

Test

Open your browser, point to test.example.com(of course replace with your real host name)

Trouble Shooting

ERROR: NoSuchKey

Error:

404 Not Found

- Code: NoSuchKey
- Message: The specified key does not exist.
- Key: index.html
- RequestId: ......
- HostId: ......

Reason: the specified index or error file is not there. Double check your settings and the files in the bucket.

ERROR: NoSuchBucket

Error:

404 Not Found

- Code: NoSuchBucket
- Message: The specified bucket does not exist
- BucketName: test.example.com
- RequestId: ......
- HostId: ......

Reason: the bucket name does not match your domain name; set your bucket name to test.example.com

ERROR: NoSuchWebsiteConfiguration

Error:

404: Not Found

- Code: NoSuchWebsiteConfiguration
- Message: The specified bucket does not have a website configuration
- BucketName: test.example.com
- RequestId: 1C661A36E8D467EB
- HostId: q7grWdZIyMJOw1Oc94nrrNteMpQu52Q154rLHHP02Tr9FAt8U71LAkUeVS0EuA+Y9JoHket/O2k=

Reason: Static Website Hosting is not enabled.

Advantages Over Hosting On EC2

  • low maintenance, no need to monitor the health of the instance
  • easy update:
    • EC2: if use git, step 1, local push; step 2, ssh to EC2 instance; step 3, pull
    • S3: use aws s3 sync. Done.