Skip to main content

How to deploy Docusaurus page using AWS S3 and CloudFront

· 4 min read
Matej Jelluš

Learning new technologies goes always better if you have something to test it on. When I wanted to start using AWS I decided to move there my blog (you are currently reading). And these are the steps it takes.

Requirements:

  • Docusaurus project
  • AWS account

Create S3 bucket

AWS S3 (Simple Storage Service) is an object storage service and we will use it to store static files generated by Docusaurus. Go to AWS console and search S3:

AWS Console

S3 Bucket, simply explained, is a "disk" where you store your files and it provides mechanisms necessary to control access to them. Click on create bucket button:

AWS create bucket

Fill the bucket name and pick region that is closest to you:

AWS bucket general configuration

Leave Object Ownership on predefined option (as recommended):

AWS bucket object ownership

You don't want anyone to access files on your bucket directly, so you can block all public access:

AWS bucket public access

When your bucket is ready, you can upload there the whole build folder from your Docusaurus project. It should look like this:

AWS S3 bucket

Create CloudFront distribution

CloudFront is a web service (CDN) that speeds up distribution of your static and dynamic web content, such as .html, .css, .js, and image files, to your users.

Search cf in AWS Console:

AWS Console CloudFront

Then click on create distribution. In origin domain choose your S3 bucket from the list and set path to /.

AWS CloudFront Origin

In the Origin access section select Origin access control settings, create control setting (where you can again use the recommended options) and copy policy, so that you can update S3 bucket afterwards.

AWS CloudFront Origin Access

You don't want your users to use unsecure http version, therefore change Viewer protocol policy to Redirect HTTP to HTTPS.

AWS CloudFront Default Cache Behavior

Last step is to set default root object to index.html. Without this, CloudFront would return error page.

AWS CloudFront Default root object

Now you can create distribution and wait until it is deployed.

Update S3 bucket policy

If you try to visit your CloudFront distribution now, it returns error, because it cannot load anything from the S3 bucket. Public access is forbidden and there is no other policy set to allow the distribution to load objects (files) from it.

You need to go back to S3 service, choose your bucket, go to Permissions tab and edit Bucket policy with JSON you copied before. It should look this:

{
"Version": "2008-10-17",
"Id": "PolicyForCloudFrontPrivateContent",
"Statement": [
{
"Sid": "AllowCloudFrontServicePrincipal",
"Effect": "Allow",
"Principal": {
"Service": "cloudfront.amazonaws.com"
},
"Action": "s3:GetObject",
"Resource": "arn:aws:s3:::<your bucket name>/*",
"Condition": {
"StringEquals": {
"AWS:SourceArn": "arn:aws:cloudfront::<your account ID>:distribution/<distribution ID>"
}
}
}
]
}

CloudFront Functions

The website is now working until you go to some blog post and try to refresh the page. CloudFront always tries to load file from S3 bucket, but you are trying to load something that does not exist (URL is /blog/some-article). You need to check the URL and return index.html file if needed (Docusaurus generates index.html file inside each folder, so /blog/some-article/index.html would work).

Go to CloudFront Functions, create new function RewriteDefaultIndex, associate it with your distribution and publish it.

function handler(event) {
var request = event.request;
var uri = request.uri;

if (uri.endsWith('/')) {
request.uri += 'index.html';
} else if (!uri.includes('.')) {
request.uri += '/index.html';
}

return request;
}

Summary

Your new Docusaurs page should now work perfectly. You can try Free CDN Performance Tool by uptrends, where you can see that users from different places are loading your page from different servers.


Did you like this post? Was it helpful? I am always learning and trying new technologies. When I struggle with something and finally manage to solve it, I share my experience.