はじめに
今まで 仕事 ではCircleCIを使ってCI/CDを構成してきたのですが、 副業 ではGitHub Actionsのほうを利用することになったので、色々調べながら試してみました。
要件としてはこんな感じです。
- PHPアプリケーションなのでデプロイには Deployer を使う
- Linux系の普通のWebサーバーにコードのみデプロイ(ECRにコンテナイメージを登録、みたいなユースケースではない)
- mainにpushされたらステージングへ、releaseにpushされたら本番へデプロイする
- デプロイはテストが通ってから実行する
試行錯誤の末、なんとか動くようになったので、完成品のyamlをみながら気をつけるポイントをメモしてみました。
.github/workflows/cd.yml のサンプル
jobs:
run-test:
# 省略
deploy-staging: # ★1
if: github.ref == 'refs/heads/main' # ★2
needs: run-test # ★3
runs-on: ubuntu-latest # ★4
steps:
- uses: actions/checkout@v2 # ★5
- name: Setup SSH for staging
run: mkdir -p ~/.ssh && echo "${{secrets.STAGING_KEY}}" > ~/.ssh/id_rsa && chmod 0600 ~/.ssh/id_rsa # ★6
- name: Setup Deployer
run: curl -LO https://deployer.org/deployer.phar && mv deployer.phar ./dep && chmod +x ./dep # ★7
- name: deploy to staging
run: ./dep deploy staging -vvv
env:
DEPLOYER_SSH_USER: foobarstaging # ★8
OAUTH_TOKEN_GITHUB: ${{secrets.OAUTH_TOKEN_GITHUB}} # ★9
deploy-production: # ★10
if: github.ref == 'refs/heads/release' # ★11
needs: run-test
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- name: Setup SSH for production
run: mkdir -p ~/.ssh && echo "${{secrets.PRODUCTION_KEY}}" > ~/.ssh/id_rsa && chmod 0600 ~/.ssh/id_rsa # ★12
- name: Setup Deployer
run: curl -LO https://deployer.org/deployer.phar && mv deployer.phar ./dep && chmod +x ./dep
- name: deploy to prod
run: ./dep deploy production -vvv # ★13
env:
DEPLOYER_SSH_USER: foobarprod
OAUTH_TOKEN_GITHUB: ${{secrets.OAUTH_TOKEN_GITHUB}}
★をつけたところが気になるところかと思います。
以下、一項目ずつメモしていきます。
★1 stagingにデプロイするジョブとして名前をつける
実行ジョブのログを見るときに、どこにデプロイしたものか後で見るためにもわかりやすい名前をつけます。
★2 mainにマージされたときだけ発動する
ifがtrueにならない場合はデプロイジョブは実行されません。
★3 テストが通ってからデプロイに入る
needsで指定したジョブが成功しない場合はデプロイジョブは実行されません。
★4 ubuntu-latestイメージでOK
テストを実行するジョブと違い、デプロイジョブではDeployerだけを動かすので、自分のアプリケーションが利用しているバージョンに縛られることはありません。
GitHub Actions提供のubuntu-latestイメージのPHPのバージョンは調べてないので知りませんが、Deployerが動くには十分でした。
★5 checkoutは必要
Deployer用の設定ファイル deploy.php
は通常のPHPファイルと同じくレポジトリにコミットされているので、checkoutは必要です。
★6 Secretsにデプロイ先サーバーにログインできる秘密鍵を置いておき、鍵ファイルに書き込む
普通にDeployerを使うとSSH接続を利用することになると思うので、デプロイ先サーバーにログインできる秘密鍵をGitHub Actionsの実行時に持たせておく必要があります。
ローカルでSSH用の鍵を新たに作成し、GitHubレポジトリの Secrets
に秘密鍵・デプロイ先サーバーでデプロイ時に使うユーザーのauthorized_keysに公開鍵を登録しておきます。
※ 人間がログインするユーザー・鍵と同じにすることはオススメしません。(問題があったときにデプロイ先サーバー側のログできりわけられないので)
鍵ファイルのパーミッションを変え忘れるとエラーになるので気をつけましょう。
★7 Deployerのpharをダウンロードして実行可能にする
予めpharを取得したものをレポジトリにコミットしておいてもいいかもしれません。
一度レポジトリにコミットしてしまうと最新版にupdateするのが面倒なのと、大した実行時間がかからんだろうという見込みのもとに、今回は直接ダウンロードすることにしています。
★8 秘密じゃない環境変数が必要なら直接envを書いても良い
SSHユーザー名を設定したのはサンプルです。
そこまで厳密に秘密にしなくても良さそうな情報を環境変数経由でDeployerに渡したいときはここで直接設定することもできます。
★9 秘密にしたい情報をdeployerに渡したいときは一回envを経由する
getenv('secrets.OAUTH_TOKEN_GITHUB')
の名前ではdeploy.phpにうまく値が渡りませんでした。
ちなみに、 GITHUB_
から始まる名前では Secrets
として登録できないよう(何度やっても登録失敗しました。予約語的なやつと思われます)なので命名は注意しましょう。
★10 productionにデプロイするジョブとして名前をつける
★1と同様、productionにデプロイすることがわかる名前をつけます。
★11 releaseブランチにpushされたとときのみ発動
本番にデプロイしたいのはreleaseブランチにpushされたときだけなので、忘れず指定します。
★12 production用の鍵をセット
ステージングのときと同様、productionサーバーにログインできる鍵をセットします。
パーミッション変更も忘れずに。
★13 deployerの向き先をproductionにしている
Deployer用の設定ファイル deploy.php
に指定したstage名を本番用のものにしています。