NRIネットコム Blog

NRIネットコム社員が様々な視点で、日々の気づきやナレッジを発信するメディアです

VuePress × AWS で始めるモダンなブログサイト入門

はじめに

こんにちは、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つほどを押さえていればブログサイトをカスタマイズして作り替えることができます。

  1. .src/.vuepress/config.ts, .src/.vuepress/theme.ts
    ブログ・著者の名前や説明、言語などのブログの基本設定を記載するファイル。
    ここでブログサイトのタイトルを変更したり、自身のプロフィールなどに書き換えたりすることができます。

  2. ./src/README.md
    トップページの md ファイル。
    ここでトップページに表示されるタイトルやコンテンツ、背景画像を変更することができます。

  3. ./src/posts/
    ブログ記事を管理するディレクトリ。
    このディレクトリ配下に md ファイルを追加していくことで記事を投稿することができます。
    (ナビゲーションバーやサイドバーも合わせて修正する必要がありますが、postsという名前を変えたり、同じ階層に別のカテゴリでmdファイルをまとめることも可能です。)

  4. .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