GitHub ActionsでエックスサーバーへのLaravelアプリのデプロイを自動化

GitHub

特定branchへのPush、Mergeをトリガーに、エックスサーバーへのデプロイが自動実行されるようにGitHub Actionsを設定する手順を解説します。

自動デプロイするための手順

下記の手順で自動でデプロイを行います。環境変数などはアプリによって扱いが変わるため注意が必要です。

  1. エックスサーバーにSSH接続
  2. git pull
  3. 依存ライブラリのインストール
  4. Laravelの設定
  5. htaccess反映

上記手順を実行するために、GitHub Actionsは下記のように設定を進めます。

  1. SSH接続情報の設定
  2. 実行ファイルの設定(今回は.ymlと.sh)

GitHubに行く前に、SSH接続と実行ディレクトリを確認しておく

想定しないディレクトリでコマンドが実行されないように、事前にSSH接続とエックスサーバーのディレクトリ構成を確認しておきます。

ちなみに、ワークフローページの右上隅にある"Cancel workflow"から、ワークフローの実行をキャンセルできます。

SSH接続情報の設定

SSH接続情報は機密情報のため、暗号化された形で保存します。Git管理しないよう注意してください。

Settings > Security > Secrets > Actions から、New repository secretで作成します。

  • SECRET_KEY: エックスサーバーSSH接続のための秘密鍵
  • USER: エックスサーバーのサーバーID(例:xs123456)
  • HOST: エックスサーバーのホスト名(例:xs123456.xsrv.jp)

実行ファイルの設定(今回は.ymlと.sh)

対象リポジトリのActionsタブ New workflowボタンから新規作成します。

先にコードを記載します。ファイル名は任意ですが、今回はauto-deploy.yml, auto-deploy.shとします。

on:
  push:
    branches:
      - develop
jobs:
  deploy:
    runs-on: ubuntu-latest
    steps:
      - name: ssh
        env:
          SECRET_KEY: ${{ secrets.SECRET_KEY }}
          USER: ${{ secrets.USER }}
          HOST: ${{ secrets.HOST }}
        run: | 
            echo "$SECRET_KEY" > secret_key
            chmod 600 secret_key
            ssh -oStrictHostKeyChecking=no ${USER}@${HOST} -i secret_key "cd (対象ディレクトリ) && sh ./.github/workflows/deploy.sh"
git checkout develop       # 対象ブランチに切り替え
git pull

# 依存ライブラリのインストール
composer install
npm install

# Laravel設定
cp .env.dev .env           
php artisan key:generate.  
php artisan migrate
php artisan cache:clear    
php artisan config:clear   
php artisan route:clear    
php artisan view:clear     

# htaccess反映
cp public/.htaccess.dev public/.htaccess

解説です。

on:
  push:
    branches:
      - develop

developブランチにpushされたときにトリガーを設定しています。

        env:
          SECRET_KEY: ${{ secrets.SECRET_KEY }}
          USER: ${{ secrets.USER }}
          HOST: ${{ secrets.HOST }}

ここでSSH接続情報を、先程設定したrepository secretsから呼び出します。

        ssh -o StrictHostKeyChecking=no ${USER}@${HOST} -i secret_key "cd (対象ディレクトリ) && sh ./.github/workflows/deploy.sh"

ここでSSH接続と接続後に行う処理を書いた.shファイルを実行しています。

-o StrictHostKeyChecking=noオプションを設定することで、未知のホスト鍵で接続するときの確認を省略して進めることができます。

(対象ディレクトリ)は、git pullするディレクトリです。「/home/ユーザー名/ドメイン名/アプリ名」のような形式になっていることが多いかと思います。

cp .env.dev .env           
php artisan key:generate.  

こちらは.envファイルの変更の反映です。シークレットキーを再生成するため、cookie依存のログインを用いているアプリの場合は、デプロイによりログイン状態が解除されてしまうため注意してください。

上記を避ける方法として、この箇所はコメントアウトして、.envのみ手動で反映する方法が挙げられます。(APP_KEYのみは引き継いで、それ以外の部分を更新するようなフローが書ければ良いのですが…)

php artisan cache:clear    
php artisan config:clear   
php artisan route:clear    
php artisan view:clear

こちらのキャッシュクリア系コマンドも、アプリの必要性に鑑みて使用・不使用を決定します。

エラーが出たポイント

Permission denied (publickey,gssapi-keyex,gssapi-with-mic).

出ました。Permission denied (publickey,gssapi-keyex,gssapi-with-mic).

ここはどうせ詰まるだろうと予想していました。原因は、パスフレーズありの鍵ペアを用いてしまっていたためです。

エックスサーバーのSSH鍵作成から、パスフレーズを入力せずに鍵ペアを生成し直して、再度repository secretsに登録すれば通りました。

パスフレーズを設定するメリットとしては、秘密鍵が流出し、その事実を検出できたときに、パスフレーズが特定されるまでに、流出した秘密鍵を無効にすることができるということが挙げられます。しかし、この事象の発生頻度は低いと考えられるため、パスフレーズは設定しなくても良い(秘密鍵をきっちり管理する)という方針です。

タイトルとURLをコピーしました