Monday, September 14, 2015

Hosting AngularJS With Amazon S3

So you built your amazing AngularJS application and now you need to host it. Sure you could create a basic Apache or NGINX server to host the application but there is another option. Amazon S3 is just a static resource host which makes it perfect for AngularJS applications since that is all AngularJS contains. Another nice feature is that Amazon S3 can be easily tied into Amazon CloudFront, so that your files can be served through a CDN. This works so long as your AngularJS application is using hash (#) or hashbang (#!) routes. I strongly recommend using the hashbang approach since that is what Google looks for when indexing a single-page application. While I am focusing on AngularJS this will also work with Ember.js, Backbone.js and any other single-page application framework using a similar navigation style.

Basic Setup

This is just a down and dirty way to create a static site with S3. If you need more information on what’s going on, then search for “hosting static site with AWS S3” in your favorite search engine.
  1. Goto the Amazon Web Services Management Console.
  2. Open the S3 control panel.
  3. Create a new bucket with your applications domain name as the name, like app.com.
  4. Now go ahead and upload your application files to the bucket. Make sure when you upload you select Make everything public on the permission step.
  5. Open the property panel for the bucket.
  6. Click Permission and then click Add more permission.
  7. Select Everyone as the Grantee and check List. This will allow a 404 to return.
  8. Save your changes.
  9. Click Static Website Hosting and then Enable website hosting.
  10. You can fill out index.html as the Index Document.
  11. Save your changes
  12. Copy the address listed under Endpoint in the Static Website Hosting panel.
  13. Now goto your application’s domain DNS control panel and add a new CNAME record pointing to the endpoint you got from AWS. It is important that the CNAME domain alias matches what you named your bucket.
  14. That’s it your site should now be working.

Handling Hashbangs

While now you can use your application, but all we really did was just set up a static site. We can go one step further. AngularJS application support routes to control what is displayed to the user. While your site already supports routes as is, it will fail if the user omits the hash or hashbang. For example app.com/#/item/1 works but app.com/item/1 fails. We can fix this using S3 by having it automatically redirect app.com/item/1 to app.com/#/item/1.
Go back to your application’s bucket properties in AWS. Under Static Website Hosting select Edit Redirection Rules. You should now see an empty text box. Use the code below, make sure to replace the HostName with your applications domain. If you want to use the hashbang method for your URLs simply change #/ to #!/.
<RoutingRules>
  <RoutingRule>
    <Condition>
    <HttpErrorCodeReturnedEquals>404</HttpErrorCodeReturnedEquals >
     </Condition>
    <Redirect>
      <HostName>[[ your application's domain name ]]</HostName>
      <ReplaceKeyPrefixWith>#/</ReplaceKeyPrefixWith>
    </Redirect>
  </RoutingRule>
</RoutingRules>
That’s it S3 will now convert URLs into the correct format.

Summary

Congratulations your AngularJS application is now being hosted by Amazon S3. A few things of note before you go. If you want to use CloudFront so your site is hosted via a CDN, the redirection rules won’t be applied by CloudFront if you link directly to the S3 bucket. You’ll have to point CloudFront to the bucket’s end point for it to work properly. I’ll be making a post to discuss setting this up at a later date. Another thing you may consider doing is redirect www to your applications domain in the DNS. Most DNS services have an easy option to make this happen but you’ll have to check your DNS service documentation. This can also work in reverse just make sure your bucket name is www.app.com.