After couple of hours struggling, I succeed in hosting my Hugo static personal website on S3 with Cloudfront service. In case I forget the pain during these hours, I decide to record the whole procedure and which part I wasted large amount of time on immediately. I will cover the lessons I learned from troubles from two perspectives: Hugo and AWS.
Hugo
Hugo is a framework written by Go to generate static websites. The doc covers details how each component works to generate the static websites.
This blog provides a good start to create our own hugo websites. I basically follow this tutorial to start my personal website repo.
During the procedure that I host my website over S3, I made some stupid mistakes. So here are some remarks. Being careful with these small details will avoid the waste of time in debugging.
-
Before generating the public folder by running
hugo
, make sure the base url in config.toml file is consistent with you domain name. It is better to start with https:// so that we can avoid mixed content issue when we applied SSL certificate to our website(will be covered in AWS section). -
For the markdown files in content folder, each has front matter. Make sure set
draft = false
so that each markdown file will have their own index.html in public folder when you runhugo
. -
Highly recommend to delete the public folder when you decide to regenerate public folder because of some mistakes. Otherwise, public folder will probably have the unexpected wrong files generated by previous version uncovered by the latest version.
AWS
Actually, Hugo can be hosted by many places like Heroku, GoDaddy, Google Cloud Storage, even Github. I choose AWS for two reasons,
- Cheap(50 cents per month + 12 dollars DNS per year)
- I would like to explore more services of AWS. They are worth trying and playing around, which might be useful for later projects
I basically used 4 services during the whole procedure of hosting a static website: S3, Route 53, Certificate Manager, Cloudfront.
S3
As most people know, S3 is the storage service of AWS. Here, S3 is used to hold the public content so that everyone can request to view the website.
I created two buckets. One holds the actual content files. The other is used to redirect requests to the real one. In this way, no matter which url people type, zhen404.com or www.zhen404.com, they will always be able to view the content.
Route 53
Route 53 is a DNS web service of AWS. I mainly used two features of Route 53, register domain name and DNS management. Apart from these two features, it has traffic management and availability management features as well.
I used to buy a domain name from another place. But I found if I use AWS to host my static website, using a domain name from another place will cause me extra work and is hard to manage. So I bought a new domain from Route 53 and connected the domain with my S3 buckets.
Certificate Manager
When we go through website online, we can always see a “locker” before url meaning this domain name is secure. After attaching a SSL certificate to the website, we will get the locker before our url. Otherwise, “Not Secure” will show up before our url and our url might be easily get attacked which is not good. AWS provide free unlimited SSL certificates. We can request SSL certificates from Certificate Manager.
Cloudfront
Cloudfront is a fast content delivery network service of AWS. We can create distributions so that the content of our website will be packaged(cached) and delivered to the edge locations all over the world. The default TTL of Cloudfront is 24 hours, which means Cloudfront will fetch the newest version of S3 content every 24 hours. The update content will show up after 24 hours. We can set it short if we would like. But doing this will increase the times of request to S3 and increase the cost of S3.
There are some benefits with Cloudfront.
- People from different places can fetch your cached content from the most closed node fast
- Cloudfront reduces the times for people directly request the S3 buckets, which could reduce the cost of S3 buckets
- Cloudfront can embed the SSL certificate with the domain to make the domain secure
Similar to the last section, here are also remarks to config AWS side correctly.
-
Create buckets name consistent with the domain name, for example zhen404.com and www.zhen404.com
-
Set CSS file as metadata of text/css in origin S3 bucket
-
Make the bucket holding content files public and set the properties as hosting static website correctly for both two buckets
-
When creating Cloudfront distribution, do not select the origin domain name in the drag down list. Copy and paste the endpoint in S3 bucket. This is very important and stuck me for hours.
-
When creating Cloudfront distribution, enter the CNAMES with both bucket names in two lines and add comma at the end of first line so that we can align this distribution to both domain names. Remember import the SSL certificate from Certificate Manager.
-
SSL certificate is only available under HTTPS protocol policy. Change the Viewer Protocol Policy to
Redirect HTTP to HTTPS
in Default Cache Behavior Settings when creating Cloudfront distribution. Otherwise, under HTTP protocol, the website will mess up due to the mixed content issue (contain https in html under http protocol). Also make sure the content in S3 bucket contents only https link in html files.
Summary
There are lots of docs and blogs talking about how to host a static website over AWS S3. I think these two links describe the whole procedure clearly,
Combining with the troubles I have met, hopefully, deploying static website is not that suffering.