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リポジトリのSettings → Secrets and variables → Actions → New repository secretから以下を登録します。
| Secret名 | 内容 |
|---|---|
SSH_KEY | 秘密鍵の内容(~/.ssh/id_rsaの内容) |
SSH_HOST | 接続先サーバのIPアドレスまたはホスト名 |
SSH_USER | SSH接続のユーザー名 |
ワークフローファイル
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リポジトリの Settings → Actions → Runners → New 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@v5 | Pythonのセットアップ |
actions/setup-node@v4 | Node.jsのセットアップ |
actions/cache@v4 | 依存関係のキャッシュ |
webfactory/ssh-agent@v0.9.0 | SSH 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"
注意点
- セルフホストRunnerはpublicリポジトリでは使用しないことを推奨します。悪意のあるコードがRunnerサーバ上で実行されるリスクがあります
- RunnerサーバとデプロイサーバのIPアドレスはGitHub Actionsのログに残るため、プライベートIPを使用する構成が望ましいです
- SSH鍵はRunnerサーバ内のファイルとして管理するため、GitHub Secretsへの登録は不要です
まとめ
GitHub Actionsを使うことで、コードのプッシュをトリガーにテスト・デプロイを自動化できます。 セルフホストRunnerを使うことでプライベートネットワーク内のサーバへのデプロイも実現できます。 RunnerユーザーとDeployユーザーを分離してSSH鍵で接続する構成にすることで、セキュリティを保ちながら安全にデプロイできます。