GithubのActionsでRsyncを利用したデプロイ
前提条件
要求内容
- Rsyncでgitのソースをサーバーにアップ
- ソースのデプロイした後に簡単にサーバーでコンマンドを実行
- Staging・本番環境の関係なくデプロイはbranchのpushで自動デプロイ
事前設定
Githubの設定
利用するレポジトリの「Settings > Secrets」に入って、サーバーへ接続情報を登録します。
SSH用の鍵を登録
SSH用のユーザー名を登録
SSH用のHostを登録
Actionsのworkflowを作成
対象リポジトリの「Actions」に入って新しくTempleteを利用して作成しても良いです。
トリガー
要求内容にも書いてますが、簡単なプロジェクトを想定しているのでStaging・本番環境の関係なくデプロイはbranchのpushで自動デプロイします。
name: deploy dev on: push: branches: - deploy/*
もし本番を手動でしたい場合は「GithubのActionsでLaravelのデプロイ」をご参考してください。
環境変数の定義
二つのブランチ(Staging、Production)についての変数を設定します。
steps: - uses: actions/checkout@v2 - name: Set staging env if: github.ref == 'refs/heads/deploy/staging' run: | echo ::set-env name=RSYNC_SOURCE::/ echo ::set-env name=RSYNC_TARGET::Staging用のDirecotry - name: Set production env if: github.ref == 'refs/heads/deploy/pro' run: | echo ::set-env name=RSYNC_SOURCE::/ echo ::set-env name=RSYNC_TARGET::本番用のDirecotry
Rsyncでソースのアップ
今回は「trendyminds/github-actions-rsync」を利用しますが、「ubuntu-latest」を利用するので直接に書いても大丈夫です。
- name: Deploy by rsync uses: trendyminds/github-actions-rsync@master with: RSYNC_OPTIONS: -avzr --delete --exclude-from=.rsyncignore RSYNC_TARGET: $RSYNC_TARGET RSYNC_SOURCE: $RSYNC_SOURCE env: SSH_PRIVATE_KEY: ${{ secrets.SSH_PRIVATE_KEY }} SSH_USERNAME: ${{ secrets.SSH_USERNAME }} SSH_HOSTNAME: ${{ secrets.SSH_HOSTNAME }}
「.rsyncignore」のファイルで対象外のファイルを定義して利用しています。
SSH接続情報の設定
速度の改善するためにCacheをする方法を入れました。情報の設定はCacheがない場合のみに作成する感じです。
- name: Cache ssh config id: cache-ssh-config uses: actions/cache@v1 with: path: /home/runner/.ssh key: ${{ runner.os }}-ssh-config-${{ hashFiles('/home/runner/.ssh/private-key-for-deploy') }} restore-keys: | ${{ runner.os }}-ssh-config- - name: Make ssh config if: steps.cache-ssh-config.outputs.cache-hit != 'true' run: | mkdir -p /home/runner/.ssh touch /home/runner/.ssh/private-key-for-deploy echo "${{ secrets.SSH_PRIVATE_KEY }}" > /home/runner/.ssh/private-key-for-deploy chmod 600 /home/runner/.ssh/private-key-for-deploy ssh-keyscan ${{ secrets.SSH_HOSTNAME }} >> ~/.ssh/known_hosts
SSHを利用してサーバーでコマンドを実行
こちらについては「appleboy/ssh-action」を使うかと思いましたが、Actionsの環境変数をscript設定に反映するのが上手く行かなかったので直接書くことにしました。
上手く行かなかった定義です。
- name: Multiple command uses: appleboy/ssh-action@master with: host: ${{ secrets.SSH_HOSTNAME }} username: ${{ secrets.SSH_USERNAME }} key: ${{ secrets.SSH_PRIVATE_KEY }} envs: RSYNC_TARGET script_stop: false script: | cd $RSYNC_TARGET
こちらが直接書いた内容です。
- name: Make shell run: | touch ./ssh-script.sh echo "cd $RSYNC_TARGET" >> ssh-script.sh echo "ls -al" >> ssh-script.sh cat ssh-script.sh - name: Excute shell run: | ssh -i ~/.ssh/private-key-for-deploy ${{ secrets.SSH_USERNAME }}@${{ secrets.SSH_HOSTNAME }} 'bash -s' < ./ssh-script.sh
完成された定義
name: deploy dev on: push: branches: - deploy/* jobs: deploy: name: deploy runs-on: ubuntu-latest steps: - uses: actions/checkout@v2 - name: Set staging env if: github.ref == 'refs/heads/deploy/staging' run: | echo ::set-env name=RSYNC_SOURCE::/ echo ::set-env name=RSYNC_TARGET::Staging用のDirectory - name: Set production env if: github.ref == 'refs/heads/deploy/pro' run: | echo ::set-env name=RSYNC_SOURCE::/ echo ::set-env name=RSYNC_TARGET::本番用のDirectory - name: Deploy by rsync uses: trendyminds/github-actions-rsync@master with: RSYNC_OPTIONS: -avzr --delete --exclude-from=.rsyncignore RSYNC_TARGET: $RSYNC_TARGET RSYNC_SOURCE: $RSYNC_SOURCE env: SSH_PRIVATE_KEY: ${{ secrets.SSH_PRIVATE_KEY }} SSH_USERNAME: ${{ secrets.SSH_USERNAME }} SSH_HOSTNAME: ${{ secrets.SSH_HOSTNAME }} - name: Cache ssh config id: cache-ssh-config uses: actions/cache@v1 with: path: /home/runner/.ssh key: ${{ runner.os }}-ssh-config-${{ hashFiles('/home/runner/.ssh/private-key-for-deploy') }} restore-keys: | ${{ runner.os }}-ssh-config- - name: Make ssh config if: steps.cache-ssh-config.outputs.cache-hit != 'true' run: | mkdir -p /home/runner/.ssh touch /home/runner/.ssh/private-key-for-deploy echo "${{ secrets.SSH_PRIVATE_KEY }}" > /home/runner/.ssh/private-key-for-deploy chmod 600 /home/runner/.ssh/private-key-for-deploy ssh-keyscan ${{ secrets.SSH_HOSTNAME }} >> ~/.ssh/known_hosts - name: Make shell run: | touch ./ssh-script.sh echo "cd $RSYNC_TARGET" >> ssh-script.sh echo "ls -al" >> ssh-script.sh cat ssh-script.sh - name: Excute shell run: | ssh -i ~/.ssh/private-key-for-deploy ${{ secrets.SSH_USERNAME }}@${{ secrets.SSH_HOSTNAME }} 'bash -s' < ./ssh-script.sh