I use S3 static website hosting for React apps in my dev and prod environments and it works great. I use a bucket naming scheme like dev-myapp-mycompany
and prod-myapp-mycompany
and have a dedicated bucket for each environment.
My team constantly creates feature branches that need testing and while I could create a new bucket for each new branch, we would have to ask for a bucket increase within a few sprints and then prune them frequently.
What I'd like to do is have a single bucket feature-myapp-mycompany
with a simple index.html
at the root which would provide a link to each app currently deployed into this feature bucket. Something like
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Feature Bucket</title>
</head>
<body>
<h1>Feature Branches</h1>
<ul>
<li>
<a href="./feature1/index.html">Feature 1</a>
</li>
<li>
<a href="./feature2/index.html">Feature 2</a>
</li>
...
<li>
<a href="./featuren/index.html">Feature n</a>
</li>
</ul>
</body>
</html>
For this the bucket structure would look like
index.html
/feature1
index.html
/static
/feature2
index.html
/static
/featuren
index.html
/static
I deploy all of the apps through the AWS cli, so it isn't a challenge to script it. I use something like
npm run build
aws s3 sync ./build s3://%bucket%/%feature% --delete --profile=%profile% --region=us-east-1
Getting the code out to the buckets is no problem. Here is where I get stuck:
My Problem:
I have the code deployed as described above but the create-react-app project defines its static dependencies from the root of the domain. So the index.html for feature1 has hrefs like /static/css/main.9fac6334.chunk.css
. This request goes and looks at the root of my bucket where there is only the primary index.html
and a "directory" for each feature. My links on the main index.html
do indeed take me to the right app index.html
but none of the script or css references are valid since they are based on the root.
Attempted Solution:
create-react-app allows you to specify a homepage
option in the package.json
that is uses to set the baseURL in your app. What I seem to need is relative paths, not absolute ones, so I tried to set the value of homepage to "./"
and then http://feature-myapp-mycompany.s3-website-us-east-1.amazonaws.com/feature1
. In both cases, the links take me to the right place for a moment and then redirect me back to the main index.html
file at the root. I know it's kind of working because I see the styling and theme of my site for a split-second before it redirects me. I even see the right requests happening in the network tab of Chrome, but after all the requests are attempted, I see it redirect back to the primary index document at the root.
Attempted Solution Continued: S3 static hosting allows redirection rules. I attempted a variety of redirect options that ended up putting me in an infinite loop for the same resource which caused the request to fail. My configuration was something like
<RoutingRules>
<RoutingRule>
<Condition>
<KeyPrefixEquals>feature1/</KeyPrefixEquals>
</Condition>
<Redirect>
<ReplaceKeyPrefixWith>feature1/</ReplaceKeyPrefixWith>
</Redirect>
</RoutingRule>
</RoutingRules>
Of course, this didn't work because it was rewriting the prefix back to the same value. Doing the same kind of redirect rules without my Attempted Solution also did not work since the request was not going to a resource with prefix feature1/
, it was going to the root.
My ideal solution:
I'd like to have some combination of the homepage
option in the package.json
and some redirect rules in place to redirect requests for static resources within each app back to the root of their respective feature branch directories. For example a request for the /static/css/main.9fac6334.chunk.css
should look inside the feature1
directory, not the root.
I'm not afraid of scripting this for the many branches we will have but I can't seem to get the options right for an individual example sub-app.
Thank you in advance for helping out and best of luck in your own coding adventures.
Hosting several subdomains in the same S3 bucket can be a great solution if you want to save time and money. Using only one S3 bucket means saving money because Amazon charges you for the size and amount of buckets, so fewer buckets mean fewer expenses.
Amazon Web Services has many innovative ways of hosting static websites and one of those is AWS S3. Today, we will learn how to deploy ReactJS app on AWS S3.
Individual Amazon S3 objects can range in size from a minimum of 0 bytes to a maximum of 5 TB. The largest object that can be uploaded in a single PUT is 5 GB.
I was able to use this SO post to accomplish what I needed to do. We already were using a cloudfront distribution for our other environments and this was very easy to set up.
Here's a summary of what we learned here:
Create a cloudfront distribution for each app pointing to your bucket with settings like the following
a. Put feature1 in bucket directory/prefix feature1/
b. Create a distribution with Origin Path /feature1
and Default root object index.html
c. Ride away clean
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With