title | emoji | type | topics | published | ||
---|---|---|---|---|---|---|
Amplifyを使えば5分でNext.js環境を公開できちゃう |
😎 |
tech |
|
true |
はい、詐欺タイトルです 何も知らない状態から Amplify を使って Next.js をデプロイするのに私は 1 日半ほど費やしました ただ、デプロイするまでにいくつかあるつまづきポイントを超えるとほんとに簡単にデプロイして公開できるので、そのつまづきポイントをご紹介できれば
- S3 + CloudFront に Next.js 環境をデプロイしたい人
- Amplify 使ってみたい人
- Amplify でのデプロイ は GitHub 連携じゃなくて CLI 使って手動でしたい人
なんと! 今なら!! たったの 5 ステップで!!!
- Amplify CLI のインストール
- デプロイ権限がある IAM の作成
amplify init
amplify add hosting
amplify publish
関係ありそうなのだけ
@aws-amplify/cli
はグローバルにインストールしてます
"@aws-amplify/cli": "4.41.2",
"next": "10.0.6",
"react": "17.0.1",
"react-dom": "17.0.1",
"typescript": "4.1.3",
Next.js は CSR でデプロイする前提です
npm install -g @aws-amplify/cli
して AmplifyCLI をインストール
:::message
yarn で @aws-amplify/cli
をインストールしない
:::
最初に amplify の設定をするのにamplify init
をする際に
自分のリポジトリ配下に@aws-amplify/cli
を yarn でインストールしたらうまくいかなかった
amplify init
の設定中に下記エラーが発生する
(node:98501) UnhandledPromiseRejectionWarning: TypeError: Cannot read property 'value' of undefined
issue を読み漁るとnpm install -g @aws-amplify/cli
してねとのこと
aws-amplify/amplify-cli#839 (comment)
今回は事前にデプロイ用の IAM が用意されていたのでやっていないが
amplify configure
すると aws console からいくつかの手順を進めると AdministratorAccess 権限を持った User を作成してくれる親切設計
https://docs.amplify.aws/cli/start/install#configure-the-amplify-cli
Amplify App を作るための初回設定 実行すると CLI 上で設定に必要な情報を登録する流れに
❯ amplify init
Initializing new Amplify CLI version...
Done initializing new version.
Scanning for plugins...
Plugin scan successful
Note: It is recommended to run this command from the root of your app directory
? Enter a name for the project {プロジェクト名}
? Enter a name for the environment dev
? Choose your default editor: Visual Studio Code
? Choose the type of app that you're building javascript
Please tell us about your project
? What javascript framework are you using react
? Source Directory Path: src
? Distribution Directory Path: out
? Build Command: yarn build
? Start Command: yarn start
Using default provider awscloudformation
? Do you want to use an AWS profile? No
? accessKeyId: ***
? secretAccessKey: ***
? region: ap-northeast-1
accessKey と secretAccessKey はデプロイ権限を持ってるやつ
無事に終わるとルート直下にamplify
ディレクトリが生成される
:::message S3 にデプロイできるように Next.js の設定を変えるんや :::
Next.js を S3 の静的ホスティング(or CloudFront で CDN 配信)するには build 時のコマンドを変えとく
下記のように build コマンドを変更すると build されたファイルが/out
ディレクトリに生成される
"scripts": {
"build": "next build && next export",
},
どのようにホスティングするか設定する
❯ amplify add hosting
? Select the plugin module to execute: Hosting with Amplify Console
? Choose a type: Manual deployment
無事に終わるとamplify/backend/hosting/amplifyhosting
が追加される
:::message
Select the plugin module to execute
で二つの選択肢が出てくるが、Hosting with Amplify Console
を選ぶんや
:::
❯ Hosting with Amplify Console (Managed hosting with custom domains, Continuous deployment)
Amazon CloudFront and S3
え、当たり前のようにAmazon CloudFront and S3
使うんしょって思ってそっち選ぶとAccessDenied の壁を超えられず
できた CloudFront や S3 のバケットの中を見る感じ、うまくできてるはずなんだけど・・
TODO: Amazon CloudFront and S3 でも公開できるようにする
amplify publish
で設定した内容でデプロイしてくれる
amplify init
を Headless mode で定義する- local で
amplify init
する - local で
amplify add hosting
する config.yml
にデプロイ step を追加する
CICD で実行できるように Headless mode なるものが Amplify CLI にはある サンプルに書かれているものを shell で定義した
#!/bin/sh
set -e
IFS='|'
ACCESS_KEY=""
SECRET_KEY=""
usage () {
cat <<EOM
Usage: $(basename "$0") [OPTION]...
-h Display help
-a ACCESS_KEY Access key of AWS
-s SECRET_KEY secret key of AWS
EOM
exit 2
}
while getopts "a:s:h" OPT
do
case $OPT in
"a" ) ACCESS_KEY="$OPTARG";;
"s" ) SECRET_KEY="$OPTARG";;
'-h'|'--help'|* ) usage ;;
esac
done
REACTCONFIG="{\
\"SourceDir\":\"src\",\
\"DistributionDir\":\"out\",\
\"BuildCommand\":\"yarn build\",\
\"StartCommand\":\"yarn start\"\
}"
AWSCLOUDFORMATIONCONFIG="{\
\"configLevel\":\"project\",\
\"useProfile\":false,\
\"profileName\":\"default\",\
\"accessKeyId\":\"$ACCESS_KEY\",\
\"secretAccessKey\":\"$SECRET_KEY\",\
\"region\":\"ap-northeast-1\"\
}"
# project-nameには任意のproject名
AMPLIFY="{\
\"projectName\":\"project-name\",\
\"envName\":\"dev\",\
\"defaultEditor\":\"code\"\
}"
FRONTEND="{\
\"frontend\":\"javascript\",\
\"framework\":\"react\",\
\"config\":$REACTCONFIG\
}"
PROVIDERS="{\
\"awscloudformation\":$AWSCLOUDFORMATIONCONFIG\
}"
amplify init \
--amplify $AMPLIFY \
--frontend $FRONTEND \
--providers $PROVIDERS \
--yes
ほぼやってることはサンプルコードと一緒だが AWS のアクセスキーとシークレットキーを CircleCI の Context から受け取れるように引数でもらってる
前段で記載した通り
プロジェクトに設定情報を保存するため、ローカルで必ず一度実行する
amplify init
に関しては定義した shell を実行すれば良き
deploy_stg:
executor: default
steps:
- checkout
- attach_workspace:
at: .
- run:
name: Install amplify cli
command: curl -sL https://aws-amplify.github.io/amplify-cli/install | bash && $SHELL
- run:
name: Update path
command: echo 'export PATH="$HOME/.amplify/bin:$PATH"' >> $BASH_ENV
- run:
name: Init amplify
# contextから環境変数は取得する
command: sh scripts/amplify_init/main.sh -a "$AWS_ACCESS_KEY_ID" -s "$AWS_SECRET_ACCESS_KEY"
- run:
name: Deploy
command: amplify publish --yes
:::message
Amplify cli のインストールはcurl -sL https://aws-amplify.github.io/amplify-cli/install | bash && $SHELL
やぞ
あと、インストールした後は path 通すんやで
:::
:::message
image: cimg/node:14.15.4
を使ってると Next の build がこけるから
yarn add sharp
しとく
:::
cimg/node:14.15.4
のコンテナ内で build すると下記のようなエラーを吐く
> Build error occurred
Error: Cannot find module 'sharp'
Require stack:
- /home/circleci/src/node_modules/next/dist/build/index.js
- /home/circleci/src/node_modules/next/dist/cli/next-build.js
- /home/circleci/src/node_modules/next/dist/bin/next
at Function.Module._resolveFilename (internal/modules/cjs/loader.js:880:15)
at Function.resolve (internal/modules/cjs/helpers.js:94:19)
at /home/circleci/src/node_modules/next/dist/build/index.js:11:1029
at /home/circleci/src/node_modules/next/dist/build/tracer.js:1:1331
at NoopTracer.withSpan (/home/circleci/src/node_modules/@opentelemetry/api/build/src/trace/NoopTracer.js:47:16)
at ProxyTracer.withSpan (/home/circleci/src/node_modules/@opentelemetry/api/build/src/trace/ProxyTracer.js:36:34)
at traceFn (/home/circleci/src/node_modules/next/dist/build/tracer.js:1:1301)
at /home/circleci/src/node_modules/next/dist/build/index.js:11:365
at async /home/circleci/src/node_modules/next/dist/build/tracer.js:1:1441 {
code: 'MODULE_NOT_FOUND',
requireStack: [
'/home/circleci/src/node_modules/next/dist/build/index.js',
'/home/circleci/src/node_modules/next/dist/cli/next-build.js',
'/home/circleci/src/node_modules/next/dist/bin/next'
]
}
error Command failed with exit code 1.
yarn add sharp
せえよとのこと
https://github.com/vercel/next.js/blob/canary/errors/install-sharp.md
Cloud Front + S3 環境だと Cloud Front 側で Basic 認証の設定するような Lambda を実装してたけど、Amplify コンソールでは画面ぽちぽちですぐ Basic 認証できる