AstroサイトをAWSにデプロイする
AWSは、Astroサイトのデプロイに使用できる、機能豊富なウェブアプリホスティングプラットフォームです。
プロジェクトをAWSにデプロイするには、AWSコンソールを使用する必要があります。(これらのアクションのほとんどは、AWS CLIを使用しても実行できます)。このガイドでは、AWSにサイトをデプロイする手順を最も基本的な方法から説明します。その後、コスト効率とパフォーマンスを向上させるための追加サービスをデモンストレーションします。
AWS Amplify
セクションタイトル: AWS AmplifyAWS Amplifyは、フロントエンドのWebおよびモバイル開発者が、AWS上で迅速かつ容易にフルスタックアプリケーションを構築できるようにするという目的のために設計されたツールと機能のセットです。
-
新しいAmplify Hostingプロジェクトを作成します。
-
リポジトリをAmplifyに接続します。
-
ビルド出力ディレクトリ
baseDirectory
を/dist
に変更します。version: 1frontend:phases:preBuild:# npmを使用していない場合は、`npm ci` を `yarn install` または `pnpm i` に変更してください。commands:- npm cibuild:commands:- npm run buildartifacts:baseDirectory: /distfiles:- '**/*'cache:paths:- node_modules/**/*
pnpm
を使用する場合は、node_modules
の代わりに pnpm store ディレクトリをキャッシュするために、設定を変更する必要があります。以下は推奨のビルド設定です.
version: 1frontend: phases: preBuild: commands: - npm i -g pnpm - pnpm config set store-dir .pnpm-store - pnpm i build: commands: - pnpm run build artifacts: baseDirectory: /dist files: - '**/*' cache: paths: - .pnpm-store/**/*
Amplifyは、あなたがリポジトリにコミットをプッシュすると、自動的にあなたのウェブサイトをデプロイし、更新します。
S3での静的ウェブサイトホスティング
セクションタイトル: S3での静的ウェブサイトホスティングS3はあらゆるアプリケーションの出発点です。プロジェクトファイルやその他のアセットが保存されます。S3はファイルの保存容量とリクエスト数に対して課金されます。S3についての詳細はAWS documentationを参照してください。
-
プロジェクト名を含んだS3バケットを作成します。
バケット名はグローバルに一意でなければなりません。プロジェクト名とサイトのドメイン名の組み合わせをお勧めします。
-
**「パブリックアクセスをすべてブロック」**を無効にします。デフォルトでは、AWS はすべてのバケットを非公開に設定しています。公開するには、バケットのプロパティにある「パブリックアクセスをブロック」のチェックを外す必要があります。
-
dist
にあるビルドしたファイルをS3にアップロードします。これは、コンソールで手動で行うか、AWS CLIを使用して行うことができます。AWS CLIを使用する場合は、AWS認証情報で認証の後に、以下のコマンドを使用できます。aws s3 cp dist/ s3://<BUCKET_NAME>/ --recursive -
パブリックアクセスを許可するために、バケットポリシーを更新します。この設定は、バケットのアクセス権限 > バケットポリシーにあります。
{"Version": "2012-10-17","Statement": [{"Sid": "PublicReadGetObject","Effect": "Allow","Principal": "*","Action": "s3:GetObject","Resource": "arn:aws:s3:::<BUCKET_NAME>/*"}]}<BUCKET_NAME>
を自分のバケット名に置き換えることを忘れないでください。 -
BucketのWebサイトホスティングを有効にします。この設定は、バケットのプロパティ > 静的ウェブサイトホスティングにあります。インデックスドキュメントを
index.html
に、エラードキュメントを404.html
に設定します。最後に、バケットのプロパティ > 静的ウェブサイトホスティングで、新しいウェブサイトのURL確認できます。シングルページアプリケーション (SPA) をデプロイする場合は、エラードキュメントを
index.html
に設定してください。
S3とCloudFront
セクションタイトル: S3とCloudFrontCloudFrontは、コンテンツ・デリバリー・ネットワーク(CDN)機能を提供するウェブサービスです。ウェブサーバーのコンテンツをキャッシュし、エンドユーザーに配信するために使用されます。CloudFrontは転送されたデータ量に応じて課金されます。CloudFrontをS3バケットに追加することで、より費用対効果が高く、より高速な配信が可能になります。
CloudFrontを使用してS3バケットをラップし、AmazonグローバルCDNネットワークを通じてプロジェクトのファイルを配信します。これにより、プロジェクトのファイルを配信するコストが削減され、サイトのパフォーマンスが向上します。
S3のセットアップ
セクションタイトル: S3のセットアップ-
プロジェクト名を含んだS3バケットを作成します。
バケット名はグローバルに一意でなければなりません。プロジェクト名とサイトのドメイン名の組み合わせをお勧めします。
-
dist
にあるビルドしたファイルをS3にアップロードします。これは、コンソールで手動で行うか、AWS CLIを使用して行うことができます。AWS CLIを使用する場合は、AWS認証情報で認証した後に、以下のコマンドを使用します。aws s3 cp dist/ s3://<BUCKET_NAME>/ --recursive -
バケットポリシーを更新し、CloudFrontからのアクセスを許可します。この設定は、バケットのアクセス権限 > バケットポリシーにあります。
{"Version": "2012-10-17","Statement": [{"Effect": "Allow","Principal": {"AWS": "arn:aws:iam::cloudfront:user/CloudFront Origin Access Identity <CLOUDFRONT_OAI_ID>"},"Action": "s3:GetObject","Resource": "arn:aws:s3:::astro-aws/*"}]}<CLOUDFRONT_OAI_ID>
をCloudFront Origin Access Identity IDの名前に置き換えることを忘れないでください。CloudFrontのオリジンアクセスアイデンティティIDは、CloudFrontの設定後にCloudFront > Origin access identitiesで確認できます。
CloudFrontのセットアップ
セクションタイトル: CloudFrontのセットアップ- 以下の値でCloudFrontディストリビューションを作成します:
- オリジンドメイン: 作成したS3バケット
- S3バケットへのアクセス: “OAIを使用する(バケットはCloudFrontのみにアクセスを制限できる)”
- オリジンアクセスアイデンティティ: 新しいOAIを作成
- ビューワーバケットポリシー: “いいえ、バケット・ポリシーを更新します。”
- ビューワープロトコルポリシー: “Redirect to HTTPS”
- デフォルトルートオブジェクト:
index.html
この設定は、パブリックインターネットからのS3バケットへのアクセスをブロックし、グローバルCDNネットワークを使用してサイトを提供します。CloudFrontの配信URLは、バケットのDistributions > Domain nameで確認できます。
CloudFront Functionsのセットアップ
セクションタイトル: CloudFront Functionsのセットアップ残念ながら、CloudFrontはデフォルトでは複数ページのsub-folder/index
ルーティングをサポートしていません。これを設定するには、CloudFront Functionsを使ってリクエストをS3の目的のオブジェクトに向ける必要があります。
-
以下のコードスニペットで新しいCloudFront関数を作成します。CloudFront関数はCloudFront > 関数にあります。
function handler(event) {var request = event.request;var uri = request.uri;// URIにファイル名が欠けているかチェックする。if (uri.endsWith('/')) {request.uri += 'index.html';}// URIにファイル拡張子が欠けているかチェックする。else if (!uri.includes('.')) {request.uri += '/index.html';}return request;} -
CloudFrontディストリビューションに関数をアタッチします。このオプションは、CloudFrontディストリビューションの設定 > ビヘイビア > 編集 > 関数で見つけることができます。
- ビューワーリクエスト - 関数タイプ: CloudFrontの関数。
- ビューワーリクエスト - 関数 ARN: 前のステップで作成した機能を選択します。
CloudFrontのエラーページのセットアップ
セクションタイトル: CloudFrontのエラーページのセットアップS3はデフォルトで、ファイルが見つからなかった場合には404エラーを、ファイルがプライベートであった場合には403エラーを返します。いずれの場合でも、ユーザーは汚いXMLエラーページを見ることとなります。
これを変更するには、CloudFrontディストリビューションの設定 > エラーページにカスタムエラーレスポンスを追加します。
-
404エラーのためのカスタムエラーレスポンスを以下の値で設定します:
- HTTPエラーコード: 404: Not Found
- エラーレスポンスをカスタマイズ: Yes
- レスポンスページのパス:
/index.html
- HTTPレスポンスコード: 200: OK
-
403エラーのためのカスタムエラーレスポンスを以下の値で設定します:
- HTTPエラーコード: 403: Forbidden
- エラーレスポンスをカスタマイズ: Yes
- レスポンスページのパス:
/index.html
- HTTPレスポンスコード: 200: OK
ベストなユーザー体験のために、プロジェクトにカスタム404エラーページを作成し、レスポンスページのパスを/404.html
にセットすることもできます。
GitHubアクションによる継続的デプロイメント
セクションタイトル: GitHubアクションによる継続的デプロイメントAWSで継続的デプロイを設定する方法はたくさんあります。GitHub 上でホストされているコードの場合、GitHub Actions を使ってコミットをプッシュするたびにウェブサイトをデプロイする方法があります。
-
AWSアカウントでIAMを使って、以下の権限で新しいポリシーを作成します。このポリシーによって、ビルドしたファイルをS3バケットにアップロードしたり、コミットをプッシュしたときにCloudFrontの配布ファイルを無効にしたりできるようになります。
{"Version": "2012-10-17","Statement": [{"Sid": "VisualEditor0","Effect": "Allow","Action": ["s3:PutObject","s3:ListBucket","s3:DeleteObject","cloudfront:CreateInvalidation"],"Resource": ["<DISTRIBUTION_ARN>","arn:aws:s3:::<BUCKET_NAME>/*","arn:aws:s3:::<BUCKET_NAME>"]}]}<DISTRIBUTION_ARN>
と<BUCKET_NAME>
を忘れずに置き換えてください。ARN はCloudFront > ディストリビューション > 詳細で確認できます。 -
新しいIAMユーザーを作成し、そのユーザーにポリシーをアタッチします。これにより、
AWS_SECRET_ACCESS_KEY
とAWS_ACCESS_KEY_ID
が提供されます。 -
以下のサンプルワークフローをあなたのリポジトリの
.github/workflows/deploy.yml
に追加し、GitHubにプッシュしてください。AWS_ACCESS_KEY_ID
、AWS_SECRET_ACCESS_KEY
、BUCKET_ID
、およびDISTRIBUTION_ID
を、GitHubリポジトリのSettings > Secrets > Actionsから”secrets”として追加する必要があります。New repository secretをクリックして、各値を追加します。name: Deploy Websiteon:push:branches:- mainjobs:deploy:runs-on: ubuntu-lateststeps:- name: Checkoutuses: actions/checkout@v3- name: Configure AWS Credentialsuses: aws-actions/configure-aws-credentials@v1with:aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }}aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}aws-region: us-east-1- name: Install modulesrun: npm ci- name: Build applicationrun: npm run build- name: Deploy to S3run: aws s3 sync --delete ./dist/ s3://${{ secrets.BUCKET_ID }}- name: Create CloudFront invalidationrun: aws cloudfront create-invalidation --distribution-id ${{ secrets.DISTRIBUTION_ID }} --paths "/*"BUCKET_ID
はS3バケットの名前です。DISTRIBUTION_ID
はCloudFrontのディストリビューションIDです。CloudFrontのディストリビューションIDはCloudFront > ディストリビューション > IDで確認できます。