クリエイター:メタボ兔

ウェブやアプリの開発者で利用する色な技術やサーバーや開発環境の設定について共有する場

GithubのActionsでRsyncを利用したデプロイ

前提条件

  • 簡単なPhpやHtmlで構成されたプロジェクト
  • composerを利用してないプロジェクト
  • Rsyncが利用出来るサーバー

要求内容

  • Rsyncでgitのソースをサーバーにアップ
  • ソースのデプロイした後に簡単にサーバーでコンマンドを実行
  • Staging・本番環境の関係なくデプロイはbranchのpushで自動デプロイ

事前設定

Githubの設定

利用するレポジトリの「Settings > Secrets」に入って、サーバーへ接続情報を登録します。

f:id:FattyRabbit:20201230130350p:plain

SSH用の鍵を登録

  • Name:SSH_PRIVATE_KEY
  • Value:ローカルのDeployerで使用している鍵(.pubでない方)の中身をコピーして入れる

SSH用のユーザー名を登録

  • Name:SSH_USERNAME
  • Value:ログインID

SSH用のHostを登録

Actionsのworkflowを作成

対象リポジトリの「Actions」に入って新しくTempleteを利用して作成しても良いです。

トリガー

要求内容にも書いてますが、簡単なプロジェクトを想定しているのでStaging・本番環境の関係なくデプロイはbranchのpushで自動デプロイします。

name: deploy dev

on:
  push:
    branches:
      - deploy/*

もし本番を手動でしたい場合は「GithubのActionsでLaravelのデプロイ」をご参考してください。

fatty-rabbit.hatenablog.com

環境変数の定義

二つのブランチ(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