はじめに
こんにちは、NRI ネットコムに新しくキャリアで入社しました永川です。普段はインフラエンジニアとして様々なシステムの開発・運用を担当しています。
今回は、VuePress と AWS を活用してブログサイトを構築する方法についてお話ししたいと思います。最近、VuePress を使ってシンプルでモダンなブログサイトを作成したので、その過程を題材に共有します。
VuePress とは
VuePress とはドキュメントやブログ向けの静的なウェブサイトを生成するオープンソースのフレームワークです。
Vue.js の生みの親である Evan You 氏により、コンテンツを主軸に置いた静的サイトの作成にフォーカスしたフレームワークとして開発されました。
いわゆる静的サイトジェネレーター (SSG) の一つで、ドキュメントやブログといった静的コンテンツに特化したツールとなっています。
動的コンテンツや更新の激しいコンテンツには向きませんが、静的な HTML ファイルをビルド時に事前に生成するので、デバイスやサーバーに負荷がかからず、ページの表示速度が非常に速いです。
また CDN (Contents Delivery Network) とも非常に相性がよく、スケーラビリティに優れているといった特徴があります。
SSG 関する詳しい説明はこちら↓
aws.amazon.com
主な機能
VuePress の主要な機能としては下記のものがあります。
Markdown から HTML を生成
自動目次生成、全文検索、多言語に対応
Vue コンポーネントを埋め込み
拡張性の高い様々なプラグイン
メリット
個人的に VuePress を使って嬉しいポイントは、
Markdown に対応している
VSCode などの使い慣れたツールを使ってドキュメントを記載可能
GitHub でドキュメントの管理をしたり、GitHub Actions を使用して CI/CD の仕組みを組みこむことが可能
のようなところだと思います。
普段開発で使用しているツールやプロセスをドキュメント作成にも適用できるところが非常に良いですね!
VuePress でブログを作る
今回作成したサイトでは VuePress のテーマの一つである VuePress Theme Hope を使用しました。VuePress 標準のテーマでも良いのですが、こういったテーマを使用することにより、さらに簡単に多機能なサイトを作成することができます。
実行環境
下記の手順は以下の実行環境で実施しています。
OS:MacOS Sonoma
MacOS, LinuxOS で動作確認をしています。Node.js:v18.17.1
v18.0以上が必要です。VuePress の環境構築に使います。npm:v9.6.7
v.8.0以上が必要です。パッケージマネージャーとして使用します。VuePress:v2.0.0-rc.9
v2.0以上が必要です。ブログのフレームワークとして使用します。
ブログ構築の手順
ここからは VuePress を使ったブログサイトの構築方法を解説したいと思います。
まず、下記のコマンドでプロジェクトを作成します。
npm init vuepress-theme-hope@latest sample-blog
その後、表示されるプロンプトに従って、言語やパッケージマネージャーなどの設定を行います。
? Select a language to display / 选择显示语言 english (US) ? Choose package manager npm ? Which bundler do you want to use? vite Generating package.json... ? Your project name sample-blog ? Your project version 2.0.0 ? Your project description A project of vuepress-theme-hope ? Your project license MIT Generating tsconfig.json... ? Does the project need multiple languages? No ? Do you need a GitHub workflow to deploy docs on GitHub pages? Yes ? What type of project do you want to create? blog Generating Template... ? Initialize a git repository? Yes Installing Deps... This may take a few minutes, please be patient. We can not correctly output progress bar from child process, so the process may look stuck. Successful Generated!
プロジェクトの作成に成功したら、以下のコマンドで開発サーバーを起動してみましょう。
npm run docs:dev
実行すると、以下のような出力が表示されます。
> sample-blog@2.0.0 docs:dev > vuepress-vite dev src ✔ Initializing and preparing data - done in 113ms vite v5.2.14 dev server running at: ➜ Local: http://localhost:8080/ ➜ Network: http://192.168.0.100:8080/ ➜ Network: http://192.168.64.1:8080/
これで、初期設定済みのブログサイトが立ち上がりました!ブラウザで http://localhost:8080/
にアクセスをすると確認をすることができます。
ブログのカスタマイズ
一部省略をしてますが初期で作成される Vuepress Theme Hope のプロジェクトは下記のフォルダ構成になっています。
. ├── .github │ └── workflows │ └── deploy-docs.yml ├── package.json └── src ├── .vuepress │ ├── config.ts │ ├── navbar.ts │ ├── public │ │ └── assets │ │ ├── icon │ │ └── images │ ├── sidebar.ts │ └── theme.ts ├── README.md └── posts ├── apple │ ├── 1.md │ ├── 2.md │ └── 3.md ├── cherry.md └── strawberry.md
このうち下記の4つほどを押さえていればブログサイトをカスタマイズして作り替えることができます。
.src/.vuepress/config.ts
,.src/.vuepress/theme.ts
ブログ・著者の名前や説明、言語などのブログの基本設定を記載するファイル。
ここでブログサイトのタイトルを変更したり、自身のプロフィールなどに書き換えたりすることができます。./src/README.md
トップページの md ファイル。
ここでトップページに表示されるタイトルやコンテンツ、背景画像を変更することができます。./src/posts/
ブログ記事を管理するディレクトリ。
このディレクトリ配下に md ファイルを追加していくことで記事を投稿することができます。
(ナビゲーションバーやサイドバーも合わせて修正する必要がありますが、posts
という名前を変えたり、同じ階層に別のカテゴリでmdファイルをまとめることも可能です。).src/.vuepress/navbar.ts
,.src/.vuepress/sidebar.ts
上部に表示されるナビゲーションバーや、サイドバーの設定ファイル。
ここでナビゲーションバーやサイドバーに表示される内容をカスタマイズすることができます。
ぜひ色々いじって試してみてください!
AWS でブログをホスティングする
ここからは、ブログを AWS で公開する手順を解説します。
VuePress の公式サイトでは GitHub Pages や Heroku, Netlify などの静的コンテンツのホスティングサービスへデプロイする方法が紹介されていますが、今回は AWS と Github Actions で同じ仕組みを作成しました。
ホスティングサービスを利用しても良いのですが、コスト面やカスタマイズ性、学習目的を考慮して AWS を選択しました。
必要な準備
AWS CLI のインストール
GitHub リポジトリへ VuePress のプロジェクトをプッシュ
Amazon S3 とAmazon CloudFront の作成
AWS のアーキテクチャは Amazon S3 ( 以下 S3 ) で静的ファイルをホスティングし、Amazon CloudFront ( 以下 CloudFront ) で配信を行うシンプルかつ一般的な構成にしています。
また CloudFront 経由のアクセスのみを許可し、S3 への直接アクセスを防ぐため以下の設定を有効化しました。
S3 のブロックパブリックアクセスの有効化
CloudFront で Origin Access Control (OAC) を使用
OAC を利用し、CloudFront 経由のアクセスだけを許可する S3 バケットポリシーを実装
こちらの設定を活用すると、バケットの非公開や最小特権アクセスの実装といった S3 のセキュリティベストプラクティス に則りつつ、より安全にブログを公開できます。
AWS CloudFormation テンプレート
上記の S3 と CloudFront の作成・設定には AWS CloudFormation テンプレートを使用しました。
このテンプレートでは以下の4つのリソースを作成しています。
ブロックパブリックアクセスを有効化したS3 バケット
CloudFront からのみアクセスを許可するバケットポリシー
S3 へのセキュアなアクセスを実現する Origin Access Control (OAC)
S3 と連携する CloudFront ディストリビューション
AWSTemplateFormatVersion: 2010-09-09 Description: Template for S3 static site with CloudFront Resources: S3StaticSiteBucket: Type: AWS::S3::Bucket Properties: PublicAccessBlockConfiguration: BlockPublicAcls: True BlockPublicPolicy: True IgnorePublicAcls: True RestrictPublicBuckets: True S3StaticSiteBucketPolicy: Type: AWS::S3::BucketPolicy DependsOn: - CloudFrontDistribution Properties: Bucket: !Ref S3StaticSiteBucket PolicyDocument: Version: "2012-10-17" Statement: - Sid: "AllowCloudFrontAccess" Effect: "Allow" Principal: Service: "cloudfront.amazonaws.com" Action: "s3:GetObject" Resource: !Sub "arn:${AWS::Partition}:s3:::${S3StaticSiteBucket}/*" Condition: StringEquals: AWS:SourceArn: !Sub "arn:${AWS::Partition}:cloudfront::${AWS::AccountId}:distribution/${CloudFrontDistribution}" OAC: Type: AWS::CloudFront::OriginAccessControl Properties: OriginAccessControlConfig: Description: Access Control Name: StaticSiteOAC OriginAccessControlOriginType: s3 SigningBehavior: always SigningProtocol: sigv4 CloudFrontDistribution: Type: AWS::CloudFront::Distribution DependsOn: - S3StaticSiteBucket - OAC Properties: DistributionConfig: DefaultCacheBehavior: AllowedMethods: - GET - HEAD CachedMethods: - GET - HEAD CachePolicyId: 658327ea-f89d-4fab-a63d-7e88639e58f6 TargetOriginId: S3StaticSiteBucket ViewerProtocolPolicy: redirect-to-https Compress: true Enabled: true Origins: - DomainName: !GetAtt S3StaticSiteBucket.DomainName Id: S3StaticSiteBucket OriginAccessControlId: !GetAtt OAC.Id S3OriginConfig: OriginAccessIdentity: "" DefaultRootObject: index.html PriceClass: PriceClass_200 ViewerCertificate: CloudFrontDefaultCertificate: true
静的ファイルのビルドとS3へのアップロード
S3 と CloudFront の作成が完了したら、VuePress のプロジェクトをビルドして、生成されたファイルを S3 バケットにアップロードします。
npm run build aws s3 sync ./src/.vuepress/dist s3://<your-bucket-name> --delete
アップロードが完了後、作成したCloudFrontのURLにアクセスするとデプロイが成功していることを確認することができます!
※ 作成直後だと、バケットポリシーの反映に時間がかかるためか Access Denied のエラーが出ることがあります。その場合は時間をおいて再度アクセスしてみてください。
GitHub Actions で運用を自動化する
最後に GitHub Actions の設定を行い、main ブランチにマージされたら自動的に新しい記事が配信される仕組みを作成します。
VuePress Theme Hope でプロジェクトを作成した時点で .github/workflows
配下にデフォルトの YMAL ファイルが準備されているため、そこに AWS にデプロイするための下記の設定を追記します。
AWS のクレデンシャルの設定
S3 バケットへのコンテンツのアップロード処理
CloudFront のキャッシュ削除処理
使用した Github Actions の YAML ファイルは下記です。
name: Deploy Docs on: push: branches: - main env: BUCKET_NAME: "<your-bucket-name>" CF_DISTRIBUTION_ID: "<your-cloudfront-distridution-id>" AWS_REGION: "<your-region>" permissions: id-token: write contents: read jobs: deploy-gh-pages: runs-on: ubuntu-latest steps: - name: Checkout uses: actions/checkout@v3 with: fetch-depth: 0 - name: Setup Node.js uses: actions/setup-node@v3 with: node-version: 18 cache: npm - name: Install Deps run: npm ci - name: Build Docs env: NODE_OPTIONS: --max_old_space_size=8192 run: npm run docs:build working-directory: ./src - name: configure aws credentials uses: aws-actions/configure-aws-credentials@v3 with: role-to-assume: ${{ secrets.IAM_ROLE_ARN }} role-session-name: deploy-static-site aws-region: ${{ env.AWS_REGION }} - name: Deploy Docs run: | aws s3 sync --exact-timestamps --delete src/.vuepress/dist s3://${{ env.BUCKET_NAME }}/ aws cloudfront create-invalidation --distribution-id ${{ env.CF_DISTRIBUTION_ID }} --paths "/*" working-directory: ./src
これで記事を作成し、その更新を mainブランチ へマージすることで自動的に公開される仕組みを作ることができました。
使い慣れたツールでブログ記事を執筆し、GitHubで管理しつつ自動で公開という一連の流れが完成したことになります!
まとめ
今回は VuePress を使ってブログサイトを作成し、AWS で公開する方法を紹介しました。
基盤を S3とCloudFrontで構築しましたが、これぐらいの小規模かつシンプルな静的サイトであれば、 CI/CD の環境の含めてまとめて作成してくれる AWS Amplify を使用してもよかったかもしれません。
また機会があれば次は Amplify を使って構築してみようと思います。
VuePress を使えばブログ以外でも簡単に静的サイトを作成することができるので、興味のある方はぜひこの記事を参考に作ってみてください!
参考URL
VuePress
AWS関連
GitHub Actions