地方在住IT系ニート

bkds

GitHub Actionsのメモ【CI/CDワークフロー設定と実例】

はじめに

GitHub Actionsは、GitHubが提供するCI/CDのための自動化ツールです。 GitHubリポジトリ内でワークフローを定義することで、コードのプッシュやプルリクエストをトリガーに自動でテスト・ビルド・デプロイを実行できます。

基本概念

概念説明
Workflow一連のプロセスを.github/workflows/内のYAMLファイルで定義
Jobワークフロー内の単位作業。並列または順次実行できる
Stepジョブ内のタスク。シェルコマンドまたはActionを実行する
Action再利用可能なコマンドセット。GitHub Marketplaceから取得できる
Runnerワークフローを実行するサーバ(GitHub提供またはセルフホスト)

ワークフローの作成

リポジトリ内に.github/workflows/ディレクトリを作成し、その中にYAMLファイル(例: main.yml)を作成します。

トリガーの種類

よく使うトリガーの例です。

on: [push]                    # 全ブランチへのpush
on:
  push:
    branches: [main]          # mainブランチへのpushのみ
on:
  pull_request:
    branches: [main]          # mainへのPRのみ
on:
  schedule:
    - cron: '0 9 * * 1-5'    # 平日9時に定期実行
on: workflow_dispatch         # 手動実行

実例1:Pythonのテスト自動化

リポジトリにコードがプッシュされるたびに、Pythonのセットアップをしてテストを実行するワークフローです。

name: CI

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

jobs:
  test:
    runs-on: ubuntu-latest
    steps:
      - name: Checkout code
        uses: actions/checkout@v4

      - name: Set up Python
        uses: actions/setup-python@v5
        with:
          python-version: '3.x'

      - name: Install dependencies
        run: pip install -r requirements.txt

      - name: Run tests
        run: pytest

実例2:リモートサーバへSSHデプロイ

GitHubからリモートサーバにSSH接続してデプロイする場合の設定です。

Secretsの設定

GitHubリポジトリのSettingsSecrets and variablesActionsNew repository secretから以下を登録します。

Secret名内容
SSH_KEY秘密鍵の内容(~/.ssh/id_rsaの内容)
SSH_HOST接続先サーバのIPアドレスまたはホスト名
SSH_USERSSH接続のユーザー名

ワークフローファイル

name: Deploy

on:
  push:
    branches: [main]

jobs:
  deploy:
    runs-on: ubuntu-latest
    steps:
      - name: Checkout code
        uses: actions/checkout@v4

      - name: Set up SSH
        uses: webfactory/ssh-agent@v0.9.0
        with:
          ssh-private-key: ${{ secrets.SSH_KEY }}

      - name: Add server to known_hosts
        run: ssh-keyscan -H ${{ secrets.SSH_HOST }} >> ~/.ssh/known_hosts

      - name: Deploy via SSH
        run: |
          ssh ${{ secrets.SSH_USER }}@${{ secrets.SSH_HOST }} << 'EOF'
            cd /path/to/project
            git pull origin main
            sudo systemctl restart myapp
          EOF

ハマったポイント

ssh-agentでSSH_KEYを登録するだけではhostname contains invalid charactersエラーが発生しました。 ssh-keyscanでサーバのホストキーをknown_hostsに登録することで解決できます。

- name: Add server to known_hosts
  run: ssh-keyscan -H ${{ secrets.SSH_HOST }} >> ~/.ssh/known_hosts

セルフホストRunnerの設定

GitHub提供のRunnerではなく、自前のサーバでRunnerを動かす構成です。 プライベートネットワーク内のサーバへのデプロイや、固有の環境が必要な場合に有効です。

構成

GitHub
  ↓ ジョブを送信
Runnerサーバ(github-runnerユーザー)
  ↓ scp / ssh
デプロイ先サーバ(deployユーザー)

Runnerサーバの設定

github-runnerユーザーの作成

sudo useradd -m -s /bin/bash github-runner

SSH鍵の生成

github-runnerユーザーでデプロイ先へのSSH鍵を生成します。

sudo -u github-runner ssh-keygen -t ed25519 \
  -f /home/github-runner/.ssh/deploy_key -N ""

生成された公開鍵を確認します。

sudo cat /home/github-runner/.ssh/deploy_key.pub

デプロイ先サーバの設定

deployユーザーの作成

sudo useradd -m -s /bin/bash deploy

公開鍵の登録

Runnerサーバで確認した公開鍵をデプロイ先サーバのdeployユーザーに登録します。

sudo mkdir -p /home/deploy/.ssh
echo "ssh-ed25519 AAAA..." | sudo tee -a /home/deploy/.ssh/authorized_keys
sudo chown -R deploy:deploy /home/deploy/.ssh
sudo chmod 700 /home/deploy/.ssh
sudo chmod 600 /home/deploy/.ssh/authorized_keys

デプロイ先ディレクトリの権限設定

deployユーザーがデプロイ先ディレクトリに書き込めるように設定します。

sudo mkdir -p /var/www/myapp
sudo chown deploy:deploy /var/www/myapp

Sudoers設定(サービス再起動が必要な場合)

deployユーザーがパスワードなしでsystemctlを実行できるように設定します。

sudo visudo

以下を追記します。

deploy ALL=(ALL) NOPASSWD: /bin/systemctl restart myapp

Runnerのインストール

GitHubリポジトリの SettingsActionsRunnersNew self-hosted runner を開き、表示されるコマンドをgithub-runnerユーザーで実行します。

# github-runnerユーザーに切り替え
sudo su - github-runner

# ディレクトリ作成とRunnerのダウンロード(GitHubの画面に表示されるコマンドを使用)
mkdir actions-runner && cd actions-runner
curl -o actions-runner-linux-x64.tar.gz -L \
  https://github.com/actions/runner/releases/download/v2.x.x/actions-runner-linux-x64-2.x.x.tar.gz
tar xzf actions-runner-linux-x64.tar.gz

# Runnerの設定(GitHubの画面に表示されるTOKENを使用)
./config.sh \
  --url https://github.com/<ユーザー>/<リポジトリ> \
  --token YOUR_TOKEN \
  --name "my-runner" \
  --labels "self-hosted,linux"

systemdサービスとして登録

# rootユーザーで実行
exit  # github-runnerユーザーから抜ける

cd /home/github-runner/actions-runner
sudo ./svc.sh install github-runner
sudo ./svc.sh start

# 状態確認
sudo ./svc.sh status

デプロイ先のknown_hostsに追加

StrictHostKeyCheckingを有効にしたまま安全に接続するため、デプロイ先のホストキーをRunnerサーバに登録しておきます。

sudo -u github-runner ssh-keyscan -H <デプロイ先のIPアドレ> \
  >> /home/github-runner/.ssh/known_hosts

ワークフローファイル

name: Deploy

on:
  push:
    branches: [main]

jobs:
  deploy:
    runs-on: self-hosted
    steps:
      - name: Checkout code
        uses: actions/checkout@v4

      - name: SCPでファイルを転送
        run: |
          scp -i /home/github-runner/.ssh/deploy_key \
              -r ./dist/* \
              deploy@<デプロイ先IP>:/var/www/myapp/

      - name: アプリを再起動
        run: |
          ssh -i /home/github-runner/.ssh/deploy_key \
              deploy@<デプロイ先IP> \
              "sudo systemctl restart myapp"

動作確認

# Runnerのログを確認
journalctl -u actions.runner.*.service -f

# Runnerの状態確認
sudo ./svc.sh status

よく使うAction一覧

Action用途
actions/checkout@v4リポジトリのコードをチェックアウト
actions/setup-python@v5Pythonのセットアップ
actions/setup-node@v4Node.jsのセットアップ
actions/cache@v4依存関係のキャッシュ
webfactory/ssh-agent@v0.9.0SSH Agentのセットアップ

環境変数とSecrets

jobs:
  build:
    runs-on: ubuntu-latest
    env:
      APP_ENV: production          # ワークフロー全体の環境変数
    steps:
      - name: Use secret
        env:
          API_KEY: ${{ secrets.API_KEY }}  # Secretを環境変数として渡す
        run: echo "API_KEY is set"

注意点

まとめ

GitHub Actionsを使うことで、コードのプッシュをトリガーにテスト・デプロイを自動化できます。 セルフホストRunnerを使うことでプライベートネットワーク内のサーバへのデプロイも実現できます。 RunnerユーザーとDeployユーザーを分離してSSH鍵で接続する構成にすることで、セキュリティを保ちながら安全にデプロイできます。

<-- Back to home
にほんブログ村 IT技術ブログ IT技術メモへ PVアクセスランキング にほんブログ村