You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何将React/Next.js构建产物部署到AWS S3并通过CloudFront运行?

问题:如何将Next.js应用部署到AWS S3 + CloudFront

我正在构建React/Next.js应用,计划将其部署至AWS S3,并通过AWS CloudFront提供服务(以该S3桶作为分发源)。我会自行处理Route53及DNS配置,将域名(例如https://myapp.example.com)映射到CloudFront分发。

官方文档提到可以用以下命令以生产模式构建并运行Next.js应用:

npm run build
npm run start

但我希望把npm run build生成的产物(可能是.next/目录的内容?)上传到S3桶,让用户访问域名时,通过CloudFront获取S3中的构建产物并直接在浏览器运行。

请问该如何实现这一需求?S3需要存储哪些内容?是否需要特殊配置才能让应用正常运行?


实现步骤与配置说明

1. 先明确Next.js的部署模式

S3只能托管静态资源,所以首先要区分你的应用类型:

  • 如果你的应用没有使用SSR(getServerSideProps/getInitialProps)、ISR等需要服务器运行的逻辑,可以用Next.js的静态导出模式,这是唯一能直接部署到S3的方案。
  • 如果依赖SSR/ISR,仅S3+CloudFront无法支撑,需要搭配Lambda@Edge或者改用Vercel等托管服务,这里只讲纯静态部署的场景。

开启静态导出的配置:
在next.config.js中添加:

module.exports = {
  output: 'export',
}

然后执行构建:

npm run build

此时项目根目录会生成out/文件夹,这就是完整的静态产物目录,直接上传它到S3即可。

2. S3需要存储的内容

静态导出后,out/目录下的所有文件都要上传到S3桶的根目录,包括:

  • 页面HTML文件(比如index.html、about.html)
  • _next/目录:包含转译后的JS、CSS、图片等静态资源(带哈希后缀,用于缓存更新)
  • public/目录下的自定义静态资源(会被复制到out/根目录)

如果没开静态导出,.next/目录包含服务器端运行代码,S3无法执行,所以不能直接使用。

3. S3桶的关键配置

  • 静态网站托管:开启该功能,设置默认首页为index.html,错误页也设为index.html(解决Next.js单页应用的路由跳转问题)。
  • 访问权限:推荐用CloudFront的Origin Access Control(OAC)或Origin Access Identity(OAI)限制仅CloudFront能访问S3资源,避免直接暴露S3桶。示例桶策略(适配OAI):
    {
      "Version": "2008-10-17",
      "Id": "PolicyForCloudFrontPrivateContent",
      "Statement": [
        {
          "Sid": "1",
          "Effect": "Allow",
          "Principal": {
            "AWS": "arn:aws:iam::cloudfront:user/CloudFront Origin Access Identity YOUR_OAI_ID"
          },
          "Action": "s3:GetObject",
          "Resource": "arn:aws:s3:::YOUR_BUCKET_NAME/*"
        }
      ]
    }
    
  • CORS配置(如果需要跨域请求):
    [
      {
        "AllowedHeaders": ["*"],
        "AllowedMethods": ["GET", "HEAD"],
        "AllowedOrigins": ["https://myapp.example.com"],
        "ExposeHeaders": []
      }
    ]
    

4. CloudFront的关键配置

  • 源设置:选择你的S3桶作为源,关联OAC/OAI,确保只有CloudFront能拉取S3资源。
  • 缓存行为:
    • 对_next/*路径的静态资源,设置长缓存时间(比如1年),因为这些资源带哈希后缀,内容更新时文件名会自动变化。
    • 对HTML文件,设置短缓存时间(比如5分钟),或者配置缓存键包含查询字符串,确保内容更新时用户能获取最新版本。
  • 错误页面:将404错误重定向到/index.html,状态码设为200,保证Next.js客户端路由正常工作。
  • 自定义域名与HTTPS:配置CloudFront使用你的自定义域名,关联AWS Certificate Manager(ACM)的SSL证书(注意证书必须在us-east-1区域申请)。

5. 上传产物到S3的方式

  • 使用AWS CLI(推荐):
    # 同步out目录到S3,删除桶中本地不存在的文件
    aws s3 sync out/ s3://YOUR_BUCKET_NAME --delete
    
  • 控制台手动上传:直接上传out/目录下的所有文件,保持原有目录结构。

常见问题排查

  • 子路由访问404:检查CloudFront错误页面配置和S3静态网站托管的错误页设置是否为index.html。
  • 资源加载失败:确认CloudFront缓存行为允许访问_next/路径,且S3桶权限配置正确。
  • 缓存更新不及时:发布新版本后,可手动触发CloudFront缓存失效,或者依赖静态资源的哈希后缀自动更新缓存。

内容的提问来源于stack exchange,提问作者hotmeatballsoup

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.17 21:50:40