小さなエンドウ豆

まだまだいろいろ勉強中

Github Actions と S3 + CloudFront を使って Nuxt アプリケーションを配信

Github Actions と S3 + CloudFront を使って Nuxt アプリケーションを配信

Nuxt.js を CloudFront で配信する方法が手軽で便利そうなのでやってみました。 Github Actions を組み合わせることによって master への push を検知して S3 へのアップロードを自動化してみます。

Nuxt

Nuxt 側での準備はほとんど必要ありません。 とりあえずプロジェクトを作成し、静的ファイルを生成します。

# プロジェクト作成
$ yarn create nuxt-app sample-app

# 静的ファイル生成
$ cd sample-app
$ yarn generate

これらを Github に push しておきます。

S3

S3 側ではバケットを作成します。 ポリシーはジェネレータを使って作成しました。

awspolicygen.s3.amazonaws.com

{
  "Version": "2012-10-17",
  "Id": "xxxxxxxxxxxxx",
  "Statement": [
    {
      "Sid": "xxxxxxxxxxxxxxxxxx",
      "Effect": "Allow",
      "Principal": "*",
      "Action": [
        "s3:GetObject"
      ],
      "Resource": ["arn:aws:s3:::{バケット名}/*"]
    }
  ]
}

Github Actions

Github Actions はワークフローを構築できる Github 上のサービスのことです。 CI / CD 環境を用意する必要がなく Github 上で起きるアクションをフックにビルドやテスト、デプロイを走らせることが出来ます。

ワークフローは Yaml 形式で記述ができ、Github 上にテンプレートがあるため容易に作成が可能です。 このファイルを .github/workflows 配下に置くと Github 側で認識されます。

構文に関しては以下のページに記載されています。

help.github.com

まずはテンプレートを選びます。 ※ AWS に関係ありそうな以下のテンプレートを選んでみましたが ECR にイメージを push するもので今回の題材とはあまり関係ありませんでした。

f:id:h-piiice16:20200104142240p:plain
テンプレートを選択

生成された yml ファイルを Github 上で少し編集します。

on:
  push:
    branches:
      - master

name: Deploy to Amazon S3

jobs:
  deploy:
    name: Deploy
    runs-on: ubuntu-latest

    steps:
    - name: Checkout
      uses: actions/checkout@v1

    - name: Setup Python 3.7 for awscli
      uses: actions/setup-python@v1
      with:
        version: '3.7'
        architecture: 'x64'

    - name: Setup Python 3.7 for awscli
      uses: actions/setup-python@v1
      with:
        version: '3.7'
        architecture: 'x64'

    - name: Build
      run: |
        yarn install
        yarn generate

    - name: Copy to s3
      env:
        AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY }}
        AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
      run: aws s3 cp ./dist ${{ secrets.S3_PATH }} --recursive --acl public-read

on 句の部分で対象とするアクションを指定します。 見たとおり master を push した際に実行されます。

jobs 配下にある run-on では実行するインスタンスを指定することができます。 Windows なんかもあるみたいです。今回はテンプレートと同じ ubuntu で行きます。

env は名前の通り環境変数を定義する場所で、AWS のアクセスキーなどを設定しました。 リポジトリの設定にある screts に AWS_ACCESS_KEY などのキーともに値を設定すると反映されます。

f:id:h-piiice16:20200105134033p:plain
github screts

次に画面右上の緑のボタンから編集した deploy.yml を作成するコミットをします。

f:id:h-piiice16:20200104142235p:plain
作成した yml ファイルを commit

コミットすると早速 Github Actions が実行されます。

f:id:h-piiice16:20200105083524p:plain
github actions の実行風景

S3 を見るとアップロードが完了していました。

CloudFront

CloudFront は AWS 製のコンテンツ配信サービス(CDN)です。 世界中にエッジサーバーがあり、それぞれでキャッシュが効いており高速にコンテンツを配信することが出来ます。

CloudFront は配信データ量による課金制になっており 10TB までなら $0.114 ととても安いです。

それでは「Create Distribution」で作って行きます。

設定したのは Origin の欄だけで S3 のバケットを選択します。(あとはデフォルトのままでいけたはず。。) location がデフォルトだと all になっているため料金を考慮して US だけにしました。

作成後、Error Page の設定が必要です。

なぜかと言うと Nuxt の動的ルーティングするページの場合(_id.vue のようなファイルの場合)html ファイルが実体として存在せず、CloudFront からすると 404 になってしまいます。
これだとまずいので CloudFront 側で 404 のとき /index.html を返すようにすると Nuxt 側で処理して正しいページを返してくれるようになります。

f:id:h-piiice16:20200105135114p:plain
Error page 設定

これで準備完了。

xxxx.cloudfront.net みたいな URL が発行されるのでアクセスすると繋がりました!

参考

tech.actindi.net