Next.js和静态 web应用的好处是,你将它们储存在对象储存里,几乎可以在任何地方运行, 比如AWS S3。但是每次手动更新这些文件可能是一件痛苦的事.

我们如何用Github Actions来自动持续部署我们的应用程序到S3?

  • 什么是GitHub Actions
  • 什么是持续部署
  • 我们怎么去构建
  • 第0步: 在GitHub上建立一个新的Next.js项目
  • 第1步: 手工创建一个用于部署next.js项目的新S3桶
  • 第2步: 创建一个新的GitHub Action工作流来自动化构建一个Next.js项目
  • 第3步: 配置一个GitHub Action,部署静态网站到S3上

什么是GitHub Actions

GitHub Actions是GitHub的一项免费服务,它允许我们用代码实现任务自动化。

我在这篇文章 里介绍了如何用它来自动化任务,比如在运行代码中的测试,并向Slack发送通知。

它们提供一种灵活的方式,在我们现有的工作流基础上为自动化运行代码。这提供了很多的可能性,比如部署我们的网站。

什么是 AWS S3?

S3(简单存储服务)是AWS的一个对象存储服务。它允许你在云上轻松存储文件,使它们在世界各地都可以使用。

它还允许你将这些文件作为一个网站使用。因为我们可以把HTML文件作为一个对象上传,我们也可以配置S3,让一个HTTP请求访问该文件。 这意味着,我们可以在S3中直接托管整个网站.

什么使持续部署?

持续部署(Continuous Deployment),通常是指将代码处在可发布的状态,自动化部署代码,缩短部署部署时间。

在这个示例中,我们将配置项目,持续将更新推送或者合并到git主分支,部署到网站。

我们怎样去构建?

我们首先要使用默认的Next.js起始模板初始化一个简单的Next.js应用,并配置将其编译成静态文件。

如果你不向创建一个Next.js项目,你甚至用一个简单的HTML文件跟着做,并不运行任何构建命令。但Next.js是构建动态网站应用的一种现代化方式,所以我将从这里开始。

随着我们的网站文件准备就绪,我们将在AWS中创建和配置一个S3桶,在S3桶上托管我们的网站。

最后,我们将创建一个新的GitHub Action工作流,当我们的主分支(main)发生新的变化时,它将自动更新S3中网站文件。

第0步:在GitHub上创建一个新的Next.js项目

我们将从Next.js的默认模板开始。

在创建你像创建项目的目录后,运行:

yarn create next-app my-static-website
# 或者
npx create-next-app my-static-website

注意: 请注意将my-static-website替换为你想选择的名称。我们将在本教程的其余部分使用这个名字。

如果进入到该目录并运行开发命令,你应该能够成功启动你的开发服务器。

cd my-static-website
yarn dev
# or
npm run dev

new-nextjs-app

New Next.js App

接下来,让我们把我们的项目配置为静态编译。

package.json文件, 把build 脚本改为 :

"build": "next build && next export",

这样做的目的时告诉Next将网站导出为静态文件,我们将它用于托管网站。

yarn build
# 或者
npm run build

一旦完成, 我们将查看 out目录,看到我们新网站的所有文件。

nextjs-build-export-output

Next.js 的静态输出

最后,我们要把它推送到GitHub上。

在你的GitHub账号中 创建一个新的仓库。然后会提供如何 添加现有项目到该仓库的说明。

一旦把你的项目推送到GitHub上,我们就做好了建立我的新网站项目的准备。

project-on-github

GitHub中的新repo

有下面的提交内容

第1步: 手动创建新的S3桶,并将Next.js项目部署到上面。

要开始使用我们的新S3桶,首先登录你的AWS账号,并进入到S3服务。

aws-s3-console

发现没有桶

我们要创建一个新桶,使用我们选择的名字命名,用于我们网址托管的S3,我们还要配置我们的S3桶,使其能够托管一个网站。

_注意: 本教程步会指导你如何在S3上托管网站,但是你可以查看我的另一个教程,该教程将一步步地 指导你在S3上托管网站

s3-bucket-website-hosting

静态网站在AWS S3上托管

当我们把S3桶配置成一个网站,我们就可以回到Next.js项目文件夹,运行我们的构建命令,然后把out文件夹中的所有文件上传到我们的新建的S3桶。

website-files-in-s3

S3桶上的静态应用

当这些文件被上传,并且我们已经为网站托管配置了S3桶,我们现在应该能看到我们的项目在网络上线运行!

nextjs-s3-website

AWS S3托管Next.js应用程序

第2步: 创建一个新的GitHub Action工作流来自动构建一个Next.js项目

首先,我们需要创建一个新的工作流程(workflow)。

如果你熟悉GitHub Actions,你可以手动创建一个,单我们将通过用户界面快速创建一个。

进入GitHub的仓库中的Action标签,点击set up a workflow yourself,来自行设置工作流。

github-actions-new-workflow

新的GitHub Action工作流

GitHub提供了一个模板,我们可以在工作流程中使用,不过我们要做一些修改。

让我们做以下工作。

  • 可选: 将文件重名为deploy.yml
  • 可选: 将workflow重名为CD (因为它与CI不同)
  • 可选: 删除所有的注释,使其更容易阅读
  • 删除on 属性中的pull_request
  • 删除所有的 steps 除了uses: actions/checkout@v2

因此,在这一点上,我们应该剩下的是:

name: CD

on:
  push:
    branches: [ main ]

jobs:
  build:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v2

仅仅这段代码会触发一个流程,会启动一个新的Ubuntu实例,并在GitHub上有新的改动推送到主分支后,拉取代码到Ubuntu上。

接下来, 当我们获取我们的代码后,我们要构建它。然后将输出文件同步到S3。

这一步将基于你的项目使用yarn还是npm有所不同。

如果你使用yarn,在 steps定义下,添加以下内容。

- uses: actions/setup-node@v1
  with:
    node-version: 12
- run: npm install -g yarn
- run: yarn install --frozen-lockfile
- run: yarn build

如果是使用npm,添加以下内容:

- uses: actions/setup-node@v1
  with:
    node-version: 12
- run: npm ci
- run: npm run build

在这两个步骤之间,我们要做的是:

  • 设置 node: 这是为了我们能够使用npm 和node 来安装和运行的脚本
  • 安装Yarn (仅对使用Yarn): 如果我们使用Yarn,我们将为其安装全局依赖,以便我们使用它
  • 安装依赖: 我们安装我们的依赖,我们使用一个特定命令,确保我们使用lock文件,以避免任何意外的软件包升级
  • 构建: 最后, 我们运行我们的构建命令,将我们的Next.js项目编译到out目录中。

现在我们可以将该该文件直接提交到我们的main分支,这触发我们的workflow的运行,我们可以子啊Actions标签里看到。

github-action-run-workflow

在GitHub Actions中新的workflow

为了看到它的运行状态,我们进入运行的workflow,选择我们的workflow,看到所有我们的项目包含的步骤。

github-action-successful-build

GitHub Action成功构建日志

随着提交!

第3步: 配置一个GitHub Action,将静态网站部署到S3上

现在我们正在自动构建我们的项目,我们想在S3中自动更新我们的网站。

为了做到这一点,我们将使用GitHub Action aws-actions/configure-aws-credentials(配置aws凭证) 和 the AWS CLI(AWS提供的命令行)。

我们使用GitHub Action 将接收我们的AWS凭证和配置,并在workflow的生命周期内使用。

目前,GitHub Action中的Ubuntu实例允许使用AWS CLI,因为它包含在其中。因此,我们将能够在workflow中使用CLI命令。

另外,我们也可以使用S3 Sync action。但是通过使用AWS CLI,我们可以获得更多的灵活性来定制我们的设置,我们可以使用它来获得额外的CLI命令,一般来说,熟悉AWS CLI也是不错的。

为了开始,让我们在workflow添加以下片段作为附加步骤。

- uses: aws-actions/configure-aws-credentials@v1
  with:
    aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }}
    aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
    aws-region: us-east-1

上面要做的是使用AWS凭证配置action,根据我们的设置来设置我们的AWS的Access Key和Secret Key还有region(区域)。

AWS Region可以自定义为你通常使用的AWS账号的任何区域,我在美国东北部,所以我设置为us-east-1

Access Key和Secret Key是你需要你的AWS账号生成的凭证。我们的代码设置方式是,我们将这些值存储在GitHub Secrets里,要防止这些密钥被泄。当action运行时,GitHub会将这些值改为星星(***),这样人们就无法访问这些密钥。

为了设置这些secrets,我们首先要在AWS生成 Access Keys

进入了AWS控制台。在用户菜单下,选择 My Security Credentials,然后选择 Create access key

aws-console-create-access-key

在AWS创建一个 Access Key

这会生成两个值 Access key IDSecret access key。必须保存好这些值,因为你将无法再次访问Secret key ID

aws-secret-access-keys

在AWS中寻找 Secret KeyAccess Key

注意: 记住不要再你的代码中包含Access KeySecret Key。这可能导致有人破坏你的AWS凭证。

下一步,在GitHub repo中,进入到 Settings -> Secrets,然后选择 New secret

在这里,我们要使用AWS keys添加到下面的secrets:

  • AWS_ACCESS_KEY_ID: your AWS Access key ID
  • AWS_SECRET_ACCESS_KEY: your AWS Secret key

当保存下来,你就应该记住这两个新的secrets

github-secrets-access-keys

在GitHub中创建Secrets

现在我们已经配置好了我们的凭证,我们应该为运行命令,将我们的项目同步到S3,做好准备。

在Github Action,添加以下步骤:

- run: aws s3 sync ./out s3://[bucket-name]

注意: 请确保[bucket-name] 替换为你的S3桶的名称。

这个命令会触发与我们的S3桶的同步(sync),使用out目录的文件,也就是我们项目构建的地方。

现在,如果我们提交我们的修改,我们可以看到,一旦提交到main分支,我们的actions会自动触发,我们构建我们的项目并同步到S3!

github-action-sync-s3-bucket

成功通过GitHub Action workflow 同步到AWS S3

注意: 请确保在设置这个action之前,你已经将S3桶配置为网站托管(包括解除S3桶权限) --否则这个action可能失败。

在这一点上,我们的项目可能看起来是一样的,因为我们对代码进行任何修改。

nextjs-s3-website

AWS S3的Next.js应用程序

但如果你做了一个代码修改,比如在pages/index.js中改变主页的标题,并提交该修改:

<h1 className={styles.title}>
  Colby's <a href="https://nextjs.org">Next.js!</a> Site
</h1>

我们可以看到,我们的修改触发了workflow的启动:

github-action-commit-workflow

新的GitHub Action workflow的触发来自代码改变

一旦我们的workflow完成,我们可以看到我们的内容已经在我们的网站上自动更新。

updated-nextjs-site-title

AWS S3托管的应用程序,代码已经更新

随着内容的提交

我们还能做什么?

设置CloudFront

这个篇文章的目的不是要经历AWS配置网站的整个过程,但是你在S3上运行网站服务,你可能在之前考虑过CloudFront。

你可以查看以下我的另一个指南,它指导你如何设置CloudFront,以及如何在S3中创建网站的手把手指南。

CloudFront的缓存失效

如果你的S3网站在CloudFront后面,有可能你会确保CloudFront没有缓存新的变化。

通过AWS CLI,我们也可以触发CloudFront的缓存失效,以确保它正在抓取最新的变化。

请看这里的文档学习更多的知识.

pull request部署

如果你不断地在pull request中的网站修改,有时候更容易看到网站的修改。

你可以设置一个新的workflow,只在pull request上运行,workflow可以根据分支或者环境动态创建一个新的桶,并在pull request上添加一个带有该URL的comment。

你也许能找到一个GitHub Action 作为你管理你pull request上带的comments,你可以查询GitHub Actions文档.

关注我,了解更多的Javascript、UX和其他有趣的事情!

原文:How to Use Github Actions to Deploy a Next.js Website to AWS S3,作者:Colby Fayock