【问题标题】:Hosting multiple React apps with one S3 bucket使用一个 S3 存储桶托管多个 React 应用程序
【发布时间】:2019-05-01 05:14:52
【问题描述】:

我在我的开发和生产环境中为 React 应用程序使用 S3 静态网站托管,它运行良好。我使用像 dev-myapp-mycompanyprod-myapp-mycompany 这样的存储桶命名方案,并且为每个环境都有一个专用的存储桶。

我的团队不断创建需要测试的功能分支,虽然我可以为每个新分支创建一个新存储桶,但我们必须在几个 sprint 内要求增加存储桶,然后经常修剪它们。

我想做的是有一个单独的存储桶feature-myapp-mycompany,在根目录下有一个简单的index.html,它将提供一个指向当前部署到此功能存储桶中的每个应用程序的链接。像

<!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>

为此,桶结构看起来像

index.html
    /feature1
        index.html
        /static
    /feature2
        index.html
        /static
    /featuren
        index.html
        /static

我通过 AWS cli 部署所有应用程序,因此编写脚本并不困难。我使用类似的东西

  1. npm run build
  2. aws s3 sync ./build s3://%bucket%/%feature% --delete --profile=%profile% --region=us-east-1

将代码放入存储桶中没有问题。这是我卡住的地方:

我的问题: 我已经按照上述方式部署了代码,但是 create-react-app 项目从域的根目录定义了它的静态依赖项。所以 feature1 的 index.html 有像/static/css/main.9fac6334.chunk.css 这样的href。此请求会查看我的存储桶的根目录,其中只有主 index.html 和每个功能的“目录”。我在主 index.html 上的链接确实将我带到了正确的应用程序 index.html 但没有任何脚本或 css 引用是有效的,因为它们是基于根的。

尝试的解决方案: create-react-app 允许您在 package.json 中指定一个 homepage 选项,用于在您的应用程序中设置 baseURL。我似乎需要的是相对路径,而不是绝对路径,所以我尝试将主页的值设置为"./",然后设置为http://feature-myapp-mycompany.s3-website-us-east-1.amazonaws.com/feature1。在这两种情况下,链接都会将我带到正确的位置片刻,然后将我重定向回根目录下的主 index.html 文件。我知道这很有效,因为在它重定向我之前,我会在一瞬间看到我的网站的样式和主题。我什至在 Chrome 的网络选项卡中看到了正确的请求,但是在尝试了所有请求之后,我看到它重定向回根目录下的主索引文档。

继续尝试的解决方案: S3 静态托管允许重定向规则。我尝试了各种重定向选项,最终使我陷入了相同资源的无限循环,从而导致请求失败。我的配置类似于

 <RoutingRules>
    <RoutingRule>
    <Condition>
      <KeyPrefixEquals>feature1/</KeyPrefixEquals>
    </Condition>
    <Redirect>
      <ReplaceKeyPrefixWith>feature1/</ReplaceKeyPrefixWith>
    </Redirect>
    </RoutingRule>
  </RoutingRules>

当然,这不起作用,因为它将前缀重写为相同的值。在没有我尝试的解决方案的情况下执行相同类型的重定向规则也不起作用,因为请求不会发送到前缀为 feature1/ 的资源,而是发送到根目录。

我的理想解决方案: 我想将package.json 中的homepage 选项和一些重定向规则结合起来,以将每个应用程序内的静态资源请求重定向回各自功能分支目录的根目录。例如,对/static/css/main.9fac6334.chunk.css 的请求应查看feature1 目录内,而不是根目录。

我不怕为我们将拥有的许多分支编写此脚本,但我似乎无法为单个示例子应用程序选择正确的选项。

提前感谢您在自己的编码冒险中提供帮助并祝您好运。

【问题讨论】:

  • 您应该看看 Amplify Console,其中包括功能分支部署 aws.amazon.com/amplify/console
  • 谢谢。我能够快速设置它,但对 cli 工具的新和不成熟感到有点沮丧。我的公司不使用 root 凭据,而是通过角色来完成所有事情,并且您关联的 cli 配置文件不尊重使用角色的配置文件。不过,在控制台上,我在几分钟内就设置好了 gpt。感谢您指出这项服务,所以我可以确定它是可能的。我很确定 amplify 只是为您包装了存储桶和云端创建,这很好,但对我来说现在没有必要。

标签: reactjs amazon-web-services redirect amazon-s3 deployment


【解决方案1】:

我能够使用this SO post 来完成我需要做的事情。我们已经在我们的其他环境中使用了云端发行版,这很容易设置。

这是我们在这里学到的总结:

  1. 绝对可以在同一个存储桶中托管多个 React 应用程序
  2. 您可以将每个应用程序放入您选择的目录/前缀中
  3. 使用如下设置为指向您的存储桶的每个应用创建一个云端分发

    一个。将feature1放入bucket目录/前缀feature1/

    b.使用 Origin Path /feature1 和 Default root object index.html 创建一个分布

    c。干净利落地离开

【讨论】:

  • 不使用 CloudFront 分配也可以吗?
  • 答案似乎是否定的。你只能有一个根对象,本质上这是设置多个。
  • 感谢您的跟进。那我看看我能做什么!
  • 澄清一下:您有效地为每个功能分支创建了一个 CF 分发,当您完成它时,您删除了分发?
  • 没错。它是一个具有与您的功能一样多的分布的存储桶。该发行版允许您为每个功能应用程序设置作为 index.html 的根对象。您也可以使用相同的概念来托管多个不相关的应用程序。您需要在一段时间后删除它们以保持在您的配额之下。如果您一致地命名发行版,则可以在 git branch delete 上使用 webhook 来禁用和删除 CD 发行版。
猜你喜欢
  • 2021-10-07
  • 2020-07-24
  • 1970-01-01
  • 1970-01-01
  • 2016-02-03
  • 1970-01-01
  • 2021-12-16
  • 2020-10-03
  • 1970-01-01
相关资源
最近更新 更多