GitHub Actionsで個人ブログのデプロイを自動化してみた

GitHub Actionsで個人ブログのデプロイを自動化してみた

ブログの記事をGitにpushするたびに手動でデプロイするのが面倒になった。GitHub Actionsでmainブランチへのpushをトリガーに自動デプロイするようにした。設定ファイルを書くだけで、無料で使えるCI/CDパイプラインが完成する。

GitHub Actionsの基本概念

まず用語を整理しておく:

用語 説明
Workflow 自動化処理全体の定義(YAMLファイル)
Job Workflow内の処理のまとまり
Step Job内の個々の処理
Action 再利用可能な処理単位(Marketplaceで公開)
Runner ジョブを実行する仮想マシン

ワークフローファイルの配置場所

.github/
└── workflows/
    └── deploy.yml   ← ここに置く

.github/workflows/以下に.ymlファイルを置くと自動で認識される。

基本的なデプロイワークフロー

以下はNext.jsのブログをVercelにデプロイする例:

name: Deploy to Vercel

on:
  push:
    branches:
      - main  # mainブランチへのpushをトリガー
  pull_request:
    branches:
      - main  # PRのプレビューデプロイ

jobs:
  deploy:
    runs-on: ubuntu-latest

    steps:
      # リポジトリのコードをチェックアウト
      - name: Checkout repository
        uses: actions/checkout@v4

      # Node.jsのセットアップ
      - name: Setup Node.js
        uses: actions/setup-node@v4
        with:
          node-version: '20'
          cache: 'npm'

      # 依存関係インストール
      - name: Install dependencies
        run: npm ci

      # ビルド
      - name: Build
        run: npm run build
        env:
          NEXT_PUBLIC_SITE_URL: ${{ secrets.SITE_URL }}

      # Vercelにデプロイ
      - name: Deploy to Vercel
        uses: amondnet/vercel-action@v25
        with:
          vercel-token: ${{ secrets.VERCEL_TOKEN }}
          vercel-org-id: ${{ secrets.VERCEL_ORG_ID }}
          vercel-project-id: ${{ secrets.VERCEL_PROJECT_ID }}
          vercel-args: '--prod'

シークレットの設定

ワークフロー内で使う機密情報はGitHub Secretsに登録する。

  1. GitHubリポジトリの「Settings」→「Secrets and variables」→「Actions」
  2. 「New repository secret」でシークレットを追加
  3. ワークフロー内で${{ secrets.SECRET_NAME }}で参照

コードにAPIキーやトークンを直書きしない。

テストを含むワークフロー

デプロイ前にテストを走らせる構成:

name: CI/CD Pipeline

on:
  push:
    branches: [main, develop]
  pull_request:
    branches: [main]

jobs:
  test:
    runs-on: ubuntu-latest

    steps:
      - uses: actions/checkout@v4

      - name: Setup Node.js
        uses: actions/setup-node@v4
        with:
          node-version: '20'
          cache: 'npm'

      - run: npm ci
      - run: npm run lint
      - run: npm test

  deploy:
    needs: test  # testジョブが成功した場合のみ実行
    runs-on: ubuntu-latest
    if: github.ref == 'refs/heads/main'  # mainブランチのみ

    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-node@v4
        with:
          node-version: '20'
          cache: 'npm'
      - run: npm ci
      - run: npm run build
      - name: Deploy
        run: ./scripts/deploy.sh
        env:
          DEPLOY_KEY: ${{ secrets.DEPLOY_KEY }}

needs: testでジョブの依存関係を定義できる。テストが落ちたら自動でデプロイをブロックしてくれる。

キャッシュで高速化する

毎回npm installすると遅い。cacheオプションでnode_modulesをキャッシュする:

- name: Setup Node.js with cache
  uses: actions/setup-node@v4
  with:
    node-version: '20'
    cache: 'npm'  # package-lock.jsonを基準にキャッシュ

初回は3分かかっていたジョブが、キャッシュ後は40秒になった。

SSHでVPSにデプロイする場合

さくらVPSやConoHaなどにSSHでデプロイする場合:

- name: Deploy via SSH
  uses: appleboy/ssh-action@v1
  with:
    host: ${{ secrets.SSH_HOST }}
    username: ${{ secrets.SSH_USER }}
    key: ${{ secrets.SSH_PRIVATE_KEY }}
    script: |
      cd /var/www/myapp
      git pull origin main
      npm ci --production
      pm2 restart myapp

SSH_PRIVATE_KEYにはSSH秘密鍵の内容をそのままシークレットに登録する。

実際に設定してみて気づいたこと

  • ワークフローのデバッグはactが便利:ローカルでGitHub Actionsを実行できる(brew install act
  • workflow_dispatchでの手動実行も設定しておく:緊急時に手動でデプロイできる
  • 並列実行で高速化:独立したジョブはneedsなしで並列実行される
on:
  push:
    branches: [main]
  workflow_dispatch:  # GitHub UIから手動実行可能にする

まとめ

GitHub Actionsでデプロイを自動化することで:

  • pushするだけでデプロイが完了する
  • テスト失敗時は自動でデプロイがブロックされる
  • ヒューマンエラーが減る
  • デプロイ履歴がGitHub上に残る

設定ファイルを一度書けば、あとは完全に自動で動く。無料枠(public repos無制限、private repoは月2000分)の範囲で個人ブログなら十分運用できる。