X
Popular Searches

How to Host a Website from S3

aws s3 logo

Chances are, you probably don’t need a full web server like NGINX running on EC2 to get your website up and running. If you’re just looking to host a static website, you can store all the content in S3, and host it from there.

Wait, I Don’t Need a Server?

If your site doesn’t use any server side processing (like PHP), simply storing the files on S3, configuring the bucket to host the site, and pointing your DNS to the bucket will replace the use of NGINX or Apache.

“Server side processing” is a lot less broad than it sounds. Just because your website is “static” does not mean it looks like a 1990s GeoCities page, with no JavaScript. All that “static” means is that all of your assets (HTML pages, JS code, CSS stylesheets) do not change in response to requests. With languages like PHP, all the processing is done on the server side; if two users request their profile page, the server will send them different pages. This can’t be done on S3, so if you’re using PHP, you’ll have to set up a real web server. This most notably applies to WordPress, which uses PHP to serve content.

However, it’s becoming increasingly common for websites to be large JavaScript applications. With a framework like React, all that needs to be delivered is one bundle.js file. It’s the job of the client, not the server, to run this file and launch the application. Apps like this can be hosted on S3 with no issues. This doesn’t get rid of your backend either—you can still have your app communicate with an API server and talk to a database, you’ll just have to authenticate requests coming from the client. Combined with AWS’s API Gateway and Lambda, you might not have to run a single EC2 server.

Don’t be fooled by the simple setup—for small sites, S3 can cut your costs down to pennies on the dollar, and because there are no servers to worry about, it scales perfectly all the way up to millions of users. You simply pay a flat fee for bandwidth in and out, as well as any associated costs for Lambda, RDS, or any other services you use with your app. Even for larger businesses deploying production applications, hosting from S3 is a very viable and cost-saving option if your app can support it.

S3 doesn’t support HTTPS for static websites, which would be a dealbreaker, but you can put it behind CloudFront (AWS’s CDN) which, in addition to improved caching and performance, can use a custom domain with HTTPS. It even has a more generous free tier for data transfer—50 GB rather than S3’s 1 GB.

Setting This Up

For this tutorial, rather than deploying simple HTML page, we’ll deploy the starter project from create-react-app, as it better shows off S3’s true potential.

After running yarn build, we’re left with the following assets in the /build folder:

react app contents

This entire folder will be copied over to S3. Head over to the S3 Management Console, and click “Create Bucket.”

create bucket

Give it a name (it must be unique among all AWS accounts), and click “Next.” You can turn on versioning in the options here, but there isn’t much else to consider. Click “Next” again.

On the next screen, you’ll want to uncheck “Block All Public Access.” This is on by default to prevent objects in buckets from being visible to the open internet, which would make your bucket unreachable. AWS will pop up with a warning that says to turn it back on unless you’re using “specific and verified use cases,” such as static website hosting. Because that’s exactly what we’re doing, you can ignore this.

turn on public access

Click “Create” on the bucket, and open it up.

You can manually drag the contents of your HTML folder into the bucket, but a better method is to use the AWS CLI to sync the entire folder up to your bucket. The command is pretty simple:

aws s3 sync . s3://bucket-name

Now, you should see your folder contents in the bucket:

bucket contents

Once everything is synced, you can configure the bucket to allow website hosting. From the properties tab, enable the “Static Website Hosting” option, and select your index file.  You can also select an error file to show users a more personalized 404.

enable static website hosting

This turns on static website hosting, but doesn’t explicitly grant read access. To do that, you’ll need to add the following bucket policy under Permissions > Bucket Policy:

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

attach bucket policy

This will pop up another warning telling you that public access is on. You can again ignore this.

Your bucket will now be viewable from the following endpoint:

http://BUCKET-NAME.s3-website.REGION.amazonaws.com/

s3 website test

Great! Everything works correctly. The client requests the bucket, which serves the index.html file, which downloads all required JS and CSS assets, and renders the spinning React logo.

However, this endpoint obviously isn’t user friendly, so you’ll probably want to configure a custom domain for your S3 site. The easiest method is to use CloudFront to serve requests, which is the only way to support HTTPS anyway. If you don’t want to use CloudFront, you can set up a custom domain using Route 53 to alias to your bucket’s default endpoint.

Head over to the CloudFront Console. Select “Create Distribution,” and choose “Web” as the type. On the next screen, under “Origin Domain Name,” select your S3 bucket from the dropdown. Make sure to also check “Redirect HTTP to HTTPS.”

enter name and redirect HTTP

Further down, you’ll want to configure your domain. Enter in your alternate domain name, and select “Custom SSL.” Request one from ACM; it may take up to half an hour to verify depending on your DNS provider, though if you’re using Route 53, you can create and verify the record automatically within a few minutes.

setup alternate domain

After that, click “Create Distribution” at the bottom, and wait about 15 minutes for CloudFront to get everything settled. Once it’s done, you’ll be able to visit your custom domain name, and see your app served directly from S3.

If you want to make version management easier, you can set up an automated deployment pipeline with AWS CodePipeline. Simply choose deployment to S3, and AWS will deploy source code updates automatically, including build artifacts.

Anthony Heddings Anthony Heddings
Anthony Heddings is the resident cloud engineer for LifeSavvy Media, a technical writer, programmer, and an expert at Amazon's AWS platform. He's written hundreds of articles for How-To Geek and CloudSavvy IT that have been read millions of times. Read Full Bio »

The above article may contain affiliate links, which help support CloudSavvy IT.