microCMSとNuxt3で作ったLPをさくらサーバーに自動デプロイする(GitHub Actions編)
はじめに
前回の記事では、シェルスクリプトを使って手動でデプロイする方法を紹介しました。
今回は、そのシェルスクリプトをベースに、GitHub Actionsで自動デプロイを実現しました!
mainブランチやstgブランチにpushするだけで、自動的にさくらサーバーにデプロイされるようになりました😸
手動デプロイから完全に解放されて、開発に集中できる環境が整いました!
背景
シェルスクリプト編では、Dockerコンテナから手動でdeploy.shを実行していました。
でも、本当は「コードをpushしたら自動でデプロイされる」のが理想ですよね。
特に、microCMSの記事更新をトリガーにして自動デプロイしたいという要望がありました。
microCMSからWebhookを受け取って、GitHubのrepository_dispatchイベントを発火させる仕組みを作ったので、CMSを更新するだけでLPも自動で更新されるようになりました!
シェルスクリプト編で作ったdeploy.shは、環境変数で設定を切り替えられるようになっていたので、GitHub Actionsでもそのまま流用できました。ありがたや🙏
使用技術・環境
- フレームワーク: Nuxt.js 3
- ビルド: SSG(静的サイト生成)
- デプロイ先: さくらサーバー
- CI/CD: GitHub Actions
- 転送方法: rsync(SSH経由)
-
トリガー:
-
main/stgブランチへのpush -
repository_dispatch(microCMSのWebhookから)
-
GitHub Actionsワークフローの全体像
まずは完成した.github/workflows/deploy.ymlの全体像です。
name: 'Nuxt3 LP Deploy'
on:
push:
branches:
- main
- stg
repository_dispatch:
types:
- update
jobs:
'Deploy':
runs-on: 'ubuntu-latest'
steps:
- name: 'Checkout repository'
uses: 'actions/checkout@v4'
- name: 'Copy package.json'
run: |
cp package.json /tmp/package.json
cat /tmp/package.json
- name: 'Setup Node.js'
uses: 'actions/setup-node@v4'
with:
node-version: '20'
cache: 'npm'
- name: 'Set config'
run: |
echo "MICROCMS_SERVICE_DOMAIN=your_service_domain" >> $GITHUB_ENV
echo "MICROCMS_API_KEY=${{ secrets.MICROCMS_API_KEY }}" >> $GITHUB_ENV
mkdir -p ~/.ssh
echo "${{ github.ref_name }}"
case ${{ github.ref_name }} in
'master'|'main')
cat prod/.env.prod >> $GITHUB_ENV
echo "${{ secrets.PROD_SSH_PRIVATE_KEY }}" > ~/.ssh/deploy_key
ssh-keyscan -H ${{ vars.PROD_REMOTE_HOST }} >> ~/.ssh/known_hosts
;;
'stg')
cat stg/.env.stg >> $GITHUB_ENV
echo "${{ secrets.STG_SSH_PRIVATE_KEY }}" > ~/.ssh/deploy_key
ssh-keyscan -H ${{ vars.STG_REMOTE_HOST }} >> ~/.ssh/known_hosts
;;
esac
chmod 600 ~/.ssh/deploy_key
- name: 'Install dependencies'
run: |
npm install
npm list
- name: 'Run Deploy.sh'
env:
SSH_KEY_PATH: ~/.ssh/deploy_key
run: |
case ${{ github.ref_name }} in
'master'|'main')
REMOTE_USER="${{ vars.PROD_REMOTE_USER }}"
REMOTE_HOST="${{ vars.PROD_REMOTE_HOST }}"
REMOTE_TARGET_DIR="${{ vars.PROD_REMOTE_TARGET_DIR }}"
;;
'stg')
REMOTE_USER="${{ vars.STG_REMOTE_USER }}"
REMOTE_HOST="${{ vars.STG_REMOTE_HOST }}"
REMOTE_TARGET_DIR="${{ vars.STG_REMOTE_TARGET_DIR }}"
;;
*)
echo "Skip deployment for branch: ${{ github.ref_name }}"
exit 0
;;
esac
set -eu
echo "Deploying..."
echo "-----------------------------------"
echo "Build process started"
echo "Command: npm run generate"
npm run generate
echo "Build completed successfully!"
echo "-----------------------------------"
echo "Start transferring build metadata files..."
echo "Creating necessary directories..."
ssh -i ${SSH_KEY_PATH} ${REMOTE_USER}@${REMOTE_HOST} "mkdir -p ${REMOTE_TARGET_DIR}/_nuxt/builds/meta"
echo "Transferring metadata files..."
rsync -vz --ignore-existing \
-e "ssh -i ${SSH_KEY_PATH} -p 22" \
".output/public/_nuxt/builds/meta/" \
"${REMOTE_USER}@${REMOTE_HOST}:${REMOTE_TARGET_DIR}/_nuxt/builds/meta/"
echo "Metadata files transferred successfully"
echo "-----------------------------------"
echo "Transferring generated files to the server..."
echo "Transfer destination: ${REMOTE_HOST}"
rsync -avz --delete \
-e "ssh -i ${SSH_KEY_PATH} -p 22" \
".output/public/" \
"${REMOTE_USER}@${REMOTE_HOST}:${REMOTE_TARGET_DIR}"
echo "-----------------------------------"
echo "Deployment completed successfully!"
echo "Check the site update"
ワークフローの処理フロー
このワークフローは大きく分けて次のステップで構成されています:
- リポジトリのチェックアウト
- Node.js環境のセットアップ
- 環境変数とSSH鍵の設定(本番/ステージングの分岐)
- 依存関係のインストール
- デプロイの実行(シェルスクリプトと同じ処理)
それぞれ詳しく見ていきます。
1. トリガーの設定
on:
push:
branches:
- main
- stg
repository_dispatch:
types:
- update
ワークフローは次の2つのタイミングで実行されます:
-
ブランチへのpush:
mainまたはstgブランチにpushしたとき -
repository_dispatch: microCMSのWebhookなどから、GitHub API経由で
repository_dispatchイベントを発火させたとき
repository_dispatchを使うことで、GitHub以外の外部サービス(この場合はmicroCMS)からも自動デプロイをトリガーできます。
2. リポジトリのチェックアウト
- name: 'Checkout repository'
uses: 'actions/checkout@v4'
GitHub Actionsでワークフローを実行するために、リポジトリのコードをチェックアウト(取得)します。
actions/checkout@v4は、GitHub公式のアクションで、リポジトリのコードを取得するためのものです。
3. Node.js環境のセットアップ
- name: 'Setup Node.js'
uses: 'actions/setup-node@v4'
with:
node-version: '20'
cache: 'npm'
Node.js 20をセットアップし、npmのキャッシュも有効化します。
cache: 'npm'により、依存関係のインストールが高速化されます(package-lock.jsonを元にキャッシュを使い回します)。
3. 環境変数とSSH鍵の設定(本番/ステージングの分岐)
- name: 'Set config'
run: |
echo "MICROCMS_SERVICE_DOMAIN=your_service_domain" >> $GITHUB_ENV
echo "MICROCMS_API_KEY=${{ secrets.MICROCMS_API_KEY }}" >> $GITHUB_ENV
mkdir -p ~/.ssh
case ${{ github.ref_name }} in
'master'|'main')
cat prod/.env.prod >> $GITHUB_ENV
echo "${{ secrets.PROD_SSH_PRIVATE_KEY }}" > ~/.ssh/deploy_key
ssh-keyscan -H ${{ vars.PROD_REMOTE_HOST }} >> ~/.ssh/known_hosts
;;
'stg')
cat stg/.env.stg >> $GITHUB_ENV
echo "${{ secrets.STG_SSH_PRIVATE_KEY }}" > ~/.ssh/deploy_key
ssh-keyscan -H ${{ vars.STG_REMOTE_HOST }} >> ~/.ssh/known_hosts
;;
esac
chmod 600 ~/.ssh/deploy_key
ここが重要なポイントです!
-
ブランチに応じた環境分岐:
github.ref_name(現在のブランチ名)で、本番環境(main)とステージング環境(stg)を自動的に切り替えます -
環境変数ファイルの読み込み:
-
cat prod/.env.prod(またはcat stg/.env.stg)で、プロジェクトルートのprod/.env.prod(またはstg/.env.stg)ファイルから環境変数を読み込んで$GITHUB_ENVに追加 - このファイルはオプションです。存在しない場合はエラーになるため、必要に応じて空ファイルを作成するか、この行を削除してください
-
-
SSH鍵の設定:
- GitHub Secretsに保存したSSH秘密鍵を
~/.ssh/deploy_keyに書き出し -
ssh-keyscanでサーバーのホスト鍵をknown_hostsに登録(初回接続時の確認をスキップ) -
chmod 600で鍵のパーミッションを設定(SSH接続には必須)
- GitHub Secretsに保存したSSH秘密鍵を
4. 依存関係のインストール
- name: 'Install dependencies'
run: |
npm install
npm list
package.jsonに基づいて依存関係をインストールします。
npm listでインストールされたパッケージを確認(デバッグ用)。
5. デプロイの実行
- name: 'Run Deploy.sh'
env:
SSH_KEY_PATH: ~/.ssh/deploy_key
run: |
case ${{ github.ref_name }} in
'master'|'main')
REMOTE_USER="${{ vars.PROD_REMOTE_USER }}"
REMOTE_HOST="${{ vars.PROD_REMOTE_HOST }}"
REMOTE_TARGET_DIR="${{ vars.PROD_REMOTE_TARGET_DIR }}"
;;
'stg')
REMOTE_USER="${{ vars.STG_REMOTE_USER }}"
REMOTE_HOST="${{ vars.STG_REMOTE_HOST }}"
REMOTE_TARGET_DIR="${{ vars.STG_REMOTE_TARGET_DIR }}"
;;
esac
set -eu
npm run generate
# ... rsyncでデプロイ ...
シェルスクリプト編で作ったデプロイ処理を、そのままGitHub Actions上で実行しています。
ブランチごとに適切なサーバー情報(ユーザー名、ホスト名、デプロイ先ディレクトリ)を設定してから、ビルドとデプロイを実行します。
重要なポイント
GitHub Secrets と Variables の使い分け
GitHub Actionsでは、SecretsとVariablesという2つの方法で値を設定できます。
-
Secrets: 機密情報(SSH秘密鍵、APIキーなど)を保存
- 例:
PROD_SSH_PRIVATE_KEY,MICROCMS_API_KEY - ワークフロー内では
${{ secrets.SECRET_NAME }}で参照 - 値は非表示で、ログにも出力されません
- 例:
-
Variables: 公開しても問題ない設定値(ホスト名、ユーザー名など)を保存
- 例:
PROD_REMOTE_HOST,PROD_REMOTE_USER - ワークフロー内では
${{ vars.VARIABLE_NAME }}で参照 - ログにも表示されますが、機密性は低い情報です
- 例:
varsとは?
varsはGitHub Variablesを参照するためのコンテキストです。${{ vars.PROD_REMOTE_USER }}のように書くことで、リポジトリのSettingsで設定したVariablesの値を取得できます。
使い分けることで、セキュリティを保ちながら柔軟に設定を管理できます。
ブランチによる環境の自動切り替え
case ${{ github.ref_name }} in
'master'|'main')
# 本番環境の設定
;;
'stg')
# ステージング環境の設定
;;
esac
github.ref_nameを使って、ブランチ名に応じて自動的に環境を切り替えます。
-
mainブランチ → 本番環境にデプロイ -
stgブランチ → ステージング環境にデプロイ
同じワークフローファイルで、複数の環境に対応できるのが便利です!
repository_dispatch で外部サービスから自動デプロイ
microCMSのWebhookからrepository_dispatchイベントを発火させることで、CMSの更新をトリガーに自動デプロイできます。
microCMS側の設定例:
- microCMSのWebhook機能で、GitHub APIを呼び出す
- 以下のようなリクエストを送信:
curl -X POST \
-H "Authorization: token YOUR_GITHUB_TOKEN" \
-H "Accept: application/vnd.github.v3+json" \
https://api.github.com/repos/YOUR_USERNAME/YOUR_REPO/dispatches \
-d '{"event_type":"update"}'
これで、microCMSの記事を更新すると自動的にLPも更新されます!
メタデータファイルの先行転送(シェルスクリプト編と同じ)
シェルスクリプト編でも紹介した通り、メタデータファイルを先に転送してから全ファイルを転送することで、デプロイ中のエラーを防いでいます。
# 1. メタデータを先に転送(上書きしない)
rsync -vz --ignore-existing ... "_nuxt/builds/meta/"
# 2. 全ファイルを転送(古いファイルは削除)
rsync -avz --delete ... ".output/public/"
詳しい理由は、シェルスクリプト編の記事を参照してください!
設定方法
1. GitHub Secrets の設定
リポジトリの Settings → Secrets and variables → Actions から、以下のSecretsを追加します:
| Secret名 | 説明 | 例 |
|---|---|---|
MICROCMS_API_KEY |
microCMSのAPIキー | xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx |
MICROCMS_SERVICE_DOMAIN |
microCMSのサービスドメイン(オプション) | your_service_domain |
PROD_SSH_PRIVATE_KEY |
本番環境用のSSH秘密鍵 | -----BEGIN OPENSSH PRIVATE KEY-----... |
STG_SSH_PRIVATE_KEY |
ステージング環境用のSSH秘密鍵 | -----BEGIN OPENSSH PRIVATE KEY-----... |
SSH秘密鍵は、さくらサーバーにSSH接続できる鍵をそのままコピー&ペーストしてください。
2. GitHub Variables の設定
同じく Settings → Secrets and variables → Actions の Variables タブで、以下を設定:
| Variable名 | 説明 | 例 |
|---|---|---|
PROD_REMOTE_USER |
本番環境のSSHユーザー名 | your_username |
PROD_REMOTE_HOST |
本番環境のホスト名 | xxx.sakura.ne.jp |
PROD_REMOTE_TARGET_DIR |
本番環境のデプロイ先ディレクトリ | /home/your_username/www |
STG_REMOTE_USER |
ステージング環境のSSHユーザー名 | your_username |
STG_REMOTE_HOST |
ステージング環境のホスト名 | xxx.sakura.ne.jp |
STG_REMOTE_TARGET_DIR |
ステージング環境のデプロイ先ディレクトリ | /home/your_username/www |
3. ワークフローファイルの配置
.github/workflows/deploy.ymlに上記のワークフローファイルを配置します。
ディレクトリ構造:
.github/
workflows/
deploy.yml
実行方法
通常のデプロイ(ブランチへのpush)
git push origin main # 本番環境にデプロイ
git push origin stg # ステージング環境にデプロイ
ブランチにpushするだけで、自動的にデプロイが開始されます!
もちろんpushでなくて、PRを作成してからのマージでもOKです。
microCMSからの自動デプロイ(repository_dispatch)
microCMSのWebhookを設定して、記事更新時にGitHub APIを呼び出すようにします。
これで、CMSを更新するだけで自動でデプロイされます。
まとめ
GitHub Actionsで自動デプロイを組むことで、以下のことが実現できました:
✅ pushするだけで自動デプロイ(手動実行不要)
✅ ブランチごとに環境を自動切り替え(本番/ステージング)
✅ microCMSからも自動デプロイ可能(repository_dispatch)
✅ シェルスクリプトをそのまま流用(環境変数設計の賜物)
✅ 高速なデプロイ(rsyncの差分転送)
シェルスクリプト編から、完全自動デプロイ編への進化ができました!
これで、開発に集中できる環境が整いました😸
自動デプロイ組んでる時、なんかめっちゃエンジニアやってる感じでおもしろかったです!