GitHub Actionsで本番環境への自動デプロイを30分で実装する

本記事では、GitHub Actionsを使用してコミット時に自動的に本番環境へデプロイするワークフローを構築します。設定ファイル作成からトラブルシューティングまで、すぐに仕事で活用できる実践的な手順を解説します。

GitHub Actionsで自動デプロイが必要な理由

継続的デリバリ(CD)の自動化により、デプロイミスの削減、デプロイ時間の短縮、チームの生産性向上を実現できます。GitHub Actionsは追加料金不要で利用でき、GitHubリポジトリとネイティブに統合されるため、セットアップが簡単です。

Jenkins、GitLab CI、CircleCIなどと比較して、GitHub Actionsはシンプルな設定とGitHub内での完結が利点です。小〜中規模プロジェクトの場合、特に導入コストが低いため推奨されます。

基本的なワークフロー設定の作成

ワークフローファイルの配置と構造

GitHub Actionsのワークフロー定義ファイルは、リポジトリのルートディレクトリに .github/workflows/ ディレクトリを作成し、YAMLファイルで記述します。以下のディレクトリ構造を準備してください。

your-repository/
├── .github/
│   └── workflows/
│       └── deploy.yml
├── src/
└── README.md

次に、基本的なデプロイワークフローを作成します。以下はNode.jsアプリケーションをレンタルサーバーにSSH経由でデプロイする例です。

name: Deploy to Production

# トリガー条件:mainブランチへのpushイベント
on:
  push:
    branches:
      - main

jobs:
  deploy:
    runs-on: ubuntu-latest
    
    steps:
      # ステップ1:リポジトリのコードをチェックアウト
      - uses: actions/checkout@v4
      
      # ステップ2:Node.jsのバージョン指定
      - name: Setup Node.js
        uses: actions/setup-node@v4
        with:
          node-version: '18'
      
      # ステップ3:依存パッケージのインストール
      - name: Install dependencies
        run: npm ci
      
      # ステップ4:ビルド実行
      - name: Build application
        run: npm run build
      
      # ステップ5:テスト実行(デプロイ前の品質担保)
      - name: Run tests
        run: npm test
      
      # ステップ6:SSH経由でサーバーにデプロイ
      - name: Deploy via SSH
        uses: appleboy/ssh-action@master
        with:
          host: ${{ secrets.SERVER_HOST }}
          username: ${{ secrets.SERVER_USER }}
          key: ${{ secrets.SERVER_SSH_KEY }}
          port: 22
          script: |
            cd /var/www/myapp
            git pull origin main
            npm ci
            npm run build
            pm2 restart myapp

GitHub Secretsの設定

上記ワークフロー内で使用される ${{ secrets.* }} プレースホルダーは、GitHub Secretsに登録した機密情報を参照します。以下の手順で設定してください。

GitHubのリポジトリページで、Settings → Secrets and variables → Actions へ移動し、以下3つのシークレットを登録します。

  • SERVER_HOST:デプロイ先サーバーのIPアドレスまたはドメイン
  • SERVER_USER:SSHログインユーザー名
  • SERVER_SSH_KEY:秘密鍵の内容(改行を含む)

秘密鍵を複数行のテキストとして登録する場合、GitHubの入力欄に直接ペーストして改行が保持されることを確認してください。

本番環境での実装パターン

本番環境・ステージング環境の分離デプロイ

実務では、ブランチごとに異なる環境へデプロイする必要があります。以下は main ブランチは本番、develop ブランチはステージング環境へデプロイする設定例です。

name: Deploy to Staging and Production

on:
  push:
    branches:
      - main
      - develop

jobs:
  deploy:
    runs-on: ubuntu-latest
    
    env:
      # デプロイ先を条件分岐で決定
      DEPLOY_ENV: ${{ github.ref == 'refs/heads/main' && 'production' || 'staging' }}
    
    steps:
      - uses: actions/checkout@v4
      
      - name: Setup Node.js
        uses: actions/setup-node@v4
        with:
          node-version: '18'
      
      - name: Install and build
        run: |
          npm ci
          npm run build
      
      - name: Deploy to ${{ env.DEPLOY_ENV }}
        uses: appleboy/ssh-action@master
        with:
          host: ${{ env.DEPLOY_ENV == 'production' && secrets.PROD_SERVER_HOST || secrets.STAGING_SERVER_HOST }}
          username: ${{ secrets.SERVER_USER }}
          key: ${{ secrets.SERVER_SSH_KEY }}
          script: |
            if [ "${{ env.DEPLOY_ENV }}" = "production" ]; then
              cd /var/www/production
              echo "Deploying to PRODUCTION"
            else
              cd /var/www/staging
              echo "Deploying to STAGING"
            fi
            git pull origin ${{ github.ref_name }}
            npm ci --production
            npm run build
            pm2 restart myapp

デプロイ前の品質チェック強化

本番環境へのデプロイリスクを最小化するため、複数の検証ステップを追加することをお勧めします。以下は静的解析、ユニットテスト、ビルド成果物の検証を含む例です。

      - name: Run linting
        run: npm run lint
      
      - name: Run unit tests
        run: npm test -- --coverage
      
      - name: Upload coverage reports
        uses: codecov/codecov-action@v3
        with:
          files: ./coverage/coverage-final.json
      
      - name: Check build artifacts
        run: |
          if [ ! -d "dist" ]; then
            echo "Build directory not found!"
            exit 1
          fi
          echo "Build artifacts verified successfully"

よくあるハマりポイントと解決策

SSH接続タイムアウトエラー

エラー内容: Error: SSH connection timeout

原因と対策:ファイアウォール設定やセキュリティグループで、GitHub ActionsのランナーIPをホワイトリスト登録する必要がある場合があります。AWSの場合、EC2セキュリティグループで以下を許可してください。

  • プロトコル:TCP
  • ポート:22(SSH)
  • ソース:140.82.112.0/20, 143.55.64.0/20(GitHub公式IP範囲)

または、より安全にするため、GitHub Actions用の専用ランナーをセルフホストする方法も検討してください。

秘密鍵形式エラー

エラー内容: Load key "private-key": invalid format

原因と対策:秘密鍵がOpenSSH形式(-----BEGIN OPENSSH PRIVATE KEY-----)である必要があります。古いRSA形式の場合、以下コマンドで変換してください。

ssh-keygen -p -N "" -m pem -f ~/.ssh/id_rsa

変換後の秘密鍵内容全体をGitHub Secretsにコピーし、改行が正しく保持されることを確認してください。

デプロイ後にアプリケーション起動しない

原因と対策:環境変数や権限が不足している可能性があります。SSH接続内でのコマンド実行は非インタラクティブシェルのため、以下を確認してください。

  • .env ファイルが本番サーバーに存在し、デプロイユーザーが読み込める権限を持っているか
  • pm2 または他のプロセスマネージャーが正しく設定されているか
  • ビルド成果物のパスが絶対パスで指定されているか

デプロイログを確認するため、以下コマンドをワークフローに追加してください。

      - name: Verify deployment
        uses: appleboy/ssh-action@master
        with:
          host: ${{ secrets.SERVER_HOST }}
          username: ${{ secrets.SERVER_USER }}
          key: ${{ secrets.SERVER_SSH_KEY }}
          script: |
            pm2 status
            pm2 logs myapp --lines 20

GitHub Actionsを使うべき場面と使うべきでない場面

使うべき場面

  • GitHubをメインリポジトリとして使用している中〜小規模プロジェクト
  • シンプルなビルド・テスト・デプロイパイプラインで十分な場合
  • 初期段階のスタートアップやオープンソースプロジェクト
  • 複数言語・複数プラットフォームのマトリックステストが必要

使うべきでない場面

  • 複雑なマイクロサービスアーキテクチャと細かいワークフロー制御が必要
  • GitLabやBitbucketをメインリポジトリとして使用している
  • オンプレミスのCIシステムと統合が必須
  • 月間数百回のビルドと長時間の実行時間が予想される(無料枠超過)

よくある質問

GitHub Actionsは、パブリックリポジトリなら無制限、プライベートリポジトリなら月間3,000分まで無料で使用できます(2025年1月時点)。超過分は従量課金されます。詳細はGitHub公式ドキュメントをご参照ください。

GitHub Actions単体では自動ロールバックの機能がありませんが、デプロイスクリプト内で set -e オプションを使用し、エラー時に前のリリースに戻すロジックを追加できます。より堅牢な構成には、Blue-Green DeploymentやCanary Deploymentの導入をお勧めします。

以下のようにトリガー条件を変更してください。

まとめ

  • GitHub Actionsは .github/workflows/ ディレクトリにYAMLファイルを配置して、シンプルなコード変更で自動デプロイを実現できます
  • GitHub Secretsに機密情報を登録し、ワークフロー内で安全に参照することが重要です
  • 本番環境では、ステージング環境でのテスト、静的解析、ユニットテストなど複数の検証ステップを追加してリスクを最小化してください
  • SSH接続タイムアウト、秘密鍵形式、デプロイ後の起動失敗は、環境設定と権限の確認で多くの場合解決できます
  • 小〜中規模プロジェクトではGitHub Actionsが十分で、複雑な要件がない限り導入をお勧めします

本記事で紹介したテンプレートを参考に、まずはシンプルな構成でワ

K
AWS・Python・生成AIを専門とするソフトウェアエンジニア。AI・クラウド・開発ワークフローの実践ガイドを執筆しています。詳しく見る →