Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Hosting multiple React apps with one S3 bucket

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

  1. npm run build
  2. 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.

like image 294
rictionaryFever Avatar asked May 01 '19 05:05

rictionaryFever


People also ask

Can we host multiple websites on S3 bucket?

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.

Can we host react website on S3?

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.

Is there any limit for S3 bucket?

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.


1 Answers

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:

  1. It is definitely possible to host multiple react apps in the same bucket
  2. You can put each app into a directory/prefix of your choosing
  3. 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

like image 127
rictionaryFever Avatar answered Oct 16 '22 06:10

rictionaryFever