はじめに
本記事では、Github Actions を利用して Xserver に Laravel を自動デプロイする流れを説明しています。
WSL 環境化で作業をしていることや、SSH キーを作成していることを前提としているので初心者向けの記事ではありません。
作業環境
- Windows11: 22H2(22621.1105)
- WSL: Ubuntu-20.04 Version 2
- Laravel: v9.19
前提条件
- Xserver に SSH 接続ができる
- GitHub アカウントを持っている
SSH 接続の設定はマニュアルがあるのでそれを参考にしてください。注意点としてパスワードフレーズ無しで SSH キーを生成して下さい。
パスフレーズ有りの SSH キーを使用すると、今回作成する GitHub Actions のワークフローの SSH 接続時にエラーになります。
ダウンロードした秘密鍵はデフォルトではXserver のユーザー名.keyという名前でダウンロードされます。その秘密鍵を WSL の.ssh/
ディレクトリ配下に配置しています。
今回使用するリポジトリ
リポジトリのディレクトリ構成は以下のようになっています。Laravel のプロジェクトが格納されているsrc
ディレクトリをサーバにデプロイしていきます。
Docker を使用した開発環境で実施していますが、自動デプロイの ワークフロー自体は開発環境に依存していませんのでご自身の環境に合わせて変更して下さい。
laravel-demo-app
├── .devcontainer
│ ├── Dockerfile
│ ├── devcontainer.json
│ ├── docker-compose.yml
│ ├── mysql
│ └── web
├── .github
│ └── workflows
│ └── deploy.yml # ←今回作成していくワークフロー
├── .vscode
│ └── launch.json
└── src # ← デプロイするLaravelプロジェクト
├── .editorconfig
├── .env
├── .env.example
├── .gitattributes
├── .gitignore
├── .prettierignore
├── .prettierrc
├── README.md
├── app
├── artisan
├── bootstrap
├── composer.json
├── composer.lock
├── config
├── database
├── lang
├── package.json
├── phpstan.neon
├── phpunit.xml
├── public
├── resources
├── routes
├── storage
├── tests
├── vendor
└── vite.config.js
ワークフローの作成
該当のリポジトリに.github/workflows
というディレクトリを作成します。そのディレクトリ配下に、ワークフローの設定を定義するために yml ファイルを作成します。
今回はdeploy.yml
と言う名前にしました。
name: deploy to production-xserver
on:
push:
branches: [main]
jobs:
deploy:
runs-on: ubuntu-latest
defaults:
run:
working-directory: ./src
steps:
- name: Setup PHP
uses: shivammathur/setup-php@v2
with:
php-version: "8.1.12"
- name: Checkout repository
uses: actions/checkout@v3
- name: Copy .env
run: php -r "file_exists('.env') || copy('.env.example', '.env');"
- name: Composer Install
run: composer install -q --no-ansi --no-interaction --no-scripts --no-progress --prefer-dist
- name: Generate key
run: php artisan key:generate
- name: Directory Permissions
run: chmod -R 777 storage bootstrap/cache
- name: Deploy to Server
uses: burnett01/rsync-deployments@5.2.1
with:
switches: -avzr --delete
path: src/
remote_path: ${{ secrets.PRODUCTION_DEPLOY_REMOTE_PATH }}
remote_host: ${{ secrets.DEPLOY_HOST }}
remote_port: ${{ secrets.DEPLOY_PORT }}
remote_user: ${{ secrets.DEPLOY_USER }}
remote_key: ${{ secrets.DEPLOY_KEY }}
基本的な設定や設定の意味など、公式ドキュメントで詳しく説明されているので興味がある方は一度目を通してみて下さい。ここでは自動デプロイするための設定に絞って説明していこうと思います。
PHP のバージョン指定
shivammathur/setup-phpというアクションを使用して PHP のバージョンを指定しています。今回は Xserver の PHP のバージョンに合わせています。
- name: Setup PHP
uses: shivammathur/setup-php@v2
with:
php-version: '8.1.12'
Composer のインストールまで
actions/checkoutはリポジトリをチェックアウトし、ワークフローがそのリポジトリにアクセスできるようにしています。ほぼどのワークフローでも使用するアクションだと思います。
詳細な設定は README に記述されています。特に複雑な処理はしないのでここでは割愛します。
- name: Checkout repository
uses: actions/checkout@v3
ここでは PHP のfile_exists メソッドを使用して.env
ファイルがリポジトリ内に存在しているか確認しています。ファイルが存在すればtrue
を返し、そうでなければfalse
を返すメソッドです。
.env
ファイルを git で管理することは無いと思うので、常に.env.example
から.env
ファイルがコピーされる処理が実行されると思います。
- name: Copy .env
run: php -r "file_exists('.env') || copy('.env.example', '.env');"
ここでは composer install を実行して Laravel の初期設定を実行しています。
- name: Composer Install
run: composer install -q --no-ansi --no-interaction --no-scripts --no-progress --prefer-dist
- name: Generate key
run: php artisan key:generate
- name: Directory Permissions
run: chmod -R 777 storage bootstrap/cache
composer のオプションに関しては以下の表にまとめました。
オプション | 意味 |
---|---|
-q (--quiet) | 実行時のメッセージを出力しない |
--no-ansi | ANSI カラーを使用せずにメッセージを出力する |
-n (--no-interaction) | 対話型のメッセージを表示しない |
--no-scripts | composer.json で指定されたスクリプトの実行を飛ばす |
--no-progress | ダウンロードの進行状況を表示させない |
--prefer-dist | インストールするパッケージを、zip 形式でダウンロードして展開する。 |
--prefer-source | インストールするパッケージを、ソースから clone する。--prefer-dist オプションの方が高速 |
自動デプロイ
- name: Deploy to Server
uses: burnett01/rsync-deployments@5.2.1
with:
switches: -avzr --delete # rsyncコマンドのオプションを指定
path: src/ # デプロイするディレクトリを指定
remote_path: ${{ secrets.PRODUCTION_DEPLOY_REMOTE_PATH }}
remote_host: ${{ secrets.DEPLOY_HOST }}
remote_port: ${{ secrets.DEPLOY_PORT }}
remote_user: ${{ secrets.DEPLOY_USER }}
remote_key: ${{ secrets.DEPLOY_KEY }}
burnett01/rsync-deploymentsというアクションを使用して、Xserver にデプロイする処理を実行します。このアクションはファイルを ssh 経由の rsync でリモートフォルダにデプロイします。
${{ }}
で指定している内容は、リポジトリの環境変数に登録したデプロイ先のサーバの情報や秘密 鍵の情報を呼び出しています。
環境変数はリポジトリの Settings → Secrets and variables → Actions で設定します。
New repository secret ボタンをクリックして環境変数を指定していきます。
オプション | 意味 |
---|---|
DEPLOY_HOST | ホスト名 |
DEPLOY_KEY | Xserver の SSH 秘密鍵(テキスト) |
DEPLOY_PORT | ポート番号 |
DEPLOY_USER | ユーザー名 |
PRODUCTION_DEPLOY_REMOTE_PATH | デプロイ先のディレクトリ |
デプロイ先のディレクトリはドメインの公開ディレクトリ直下に配置するのではなく、Xserver に SSH 接続した際のホームディレクトリ配下にproduction/laravel-demo-app
と言うディレクトリを作成して、そこを指定しています。
なので、PRODUCTION_DEPLOY_REMOTE_PATHには$HOME/production/laravel-demo-app
を指定しています。$HOME
はユーザーのホームディレクトリの環境変数ですので、契約したサーバ毎に環境は異なってきます。
コマンドから確認することも出来ます。
$ echo $HOME
/home/ユーザー名
秘密鍵の登録
DEPLOY_KEY の設定では作成した秘密鍵の内容を指定します。
秘密鍵のコピーはコマンドから実行すると不要な空白など含まれないので便利です。WSL 上から Windows 上のクリップボードにコピーするには以下のコマンドを実行します。
cat ~/.ssh/xs010410.key | clip.exe
ブランチに push する
ワークフローを作成したら main ブランチに push して正常に動作するか確認します。エラーなく実行が完了すると下記の画像のよう表示になります。
Xserver で公開設定
Xserver 側で$HOME/production/laravel-demo-app
を公開する設定をします。前提として以下のことを実施しておいて下さい。
- ドメイン、もしくはサブドメインを取得して Web サイトを公開できる領域を確保しておく
今回はサブドメインとしてdemo-app.hn-pgtech.com
を作成しているので、そこにシンボリックリンクを作成していきます。シンボリックリンクとは Windows で言うところのショートカットのようなものでhttps://demo-app.hn-pgtech.com/laravel-demo-app/
にアクセスすると、$HOME/production/laravel-demo-app/public
を参照する設定を行います。
$ ln -s $HOME/production/laravel-demo-app/public $HOME/hn-pgtech.com/public_html/demo-app.hn-pgtech.com/laravel-demo-app
https://demo-app.hn-pgtech.com/laravel-demo-app/ にアクセスして Laravel のトップページが表示されたら正常に動作しています。
データベース接続設定
.env
ファイルをワークフロー内で.env.example
から作成していますが、データベースへの接続やデバッグをfalse
にする設定を行っていないので本番環境用の設定をします。
.env
ファイルの内容も Secrets 環境変数に指定していきます。
Xserver の管理画面で今回使用するデータベースは作成しておいて下さい。ユーザー名とパスワードは.env
ファイルに指定するので控えておいてください。
管理画面からデータベースを作成する方法は以下のマニュアルを参照して下さい。
base64 でエンコードした.env の内容を登録する
本番環境用の.env
ファイルの内容を Secrets 環境変数に登録して、ワークフロー中でその内容を出力すれば実現できると考えていたのですが、改行が空白に変換されておりphp artisan key:generate
実行時にエラーとなっていました。
Failed to parse dotenv file. Encountered unexpected whitespace at
色々検索していたところ、.env
ファイルの内容を base64 でエンコードして Secrets 環境変数に登録し、ワークフロー内でデコードすれば改行も含まれた内容を登録できました。以下の記事を参考にさせてもらいました。
base64 に関してここでは深く触れませんが、データを 64 種類の英数字a~z, A~z
と一部の記号+
、-
を用いてエンコードする方式です。以下の記事が大変参考になったので、もっと深く知りたい方は読んでみて下さい。
.env
ファイルの内容のエンコードはbase64 エンコード/デコードツールを使用しました。
エンコードしたい.env
ファイルの内容を貼り付けて base64 に変換します。
変換されたコードを Secrets 環境変数に登録して下さい。
yml ファイルの修正
yml ファイルに.env
に関する記述を追記します。
name: deploy to production-xserver
on:
push:
branches: [main]
jobs:
deploy:
runs-on: ubuntu-latest
defaults:
run:
working-directory: ./src
steps:
- name: Setup PHP
uses: shivammathur/setup-php@v2
with:
php-version: "8.1.12"
- name: Checkout repository
uses: actions/checkout@v3
+ - name: Setting .env
+ env:
+ PRODUCTION_LARAVEL_ENV: ${{ secrets.PRODUCTION_LARAVEL_ENV }}
+ run: |
php -r "file_exists('.env') || copy('.env.example', '.env');"
+ echo $PRODUCTION_LARAVEL_ENV | base64 --decode > .env
- name: Composer Install
run: composer install -q --no-ansi --no-interaction --no-scripts --no-progress --prefer-dist
- name: Generate key
run: php artisan key:generate
- name: Directory Permissions
run: chmod -R 777 storage bootstrap/cache
- name: Deploy to Server
uses: burnett01/rsync-deployments@5.2.1
with:
switches: -avzr --delete
path: src/
remote_path: ${{ secrets.PRODUCTION_DEPLOY_REMOTE_PATH }}
remote_host: ${{ secrets.DEPLOY_HOST }}
remote_port: ${{ secrets.DEPLOY_PORT }}
remote_user: ${{ secrets.DEPLOY_USER }}
remote_key: ${{ secrets.DEPLOY_KEY }}
修正した内容を説明していきます。
- name: Setting .env
ステップの名前をCopy .env
から変更しました。
env:
PRODUCTION_LARAVEL_ENV: ${{ secrets.PRODUCTION_LARAVEL_ENV }}
ステップごとに使用する環境変数を設定しています。設定した環境変数をecho $PRODUCTION_LARAVEL_ENV
のようにステップ内で展開することが出来ます。
ここで指定している値は先程 base64 に変換した.env
ファイルの内容になります。
run: |
php -r "file_exists('.env') || copy('.env.example', '.env');"
echo $PRODUCTION_LARAVEL_ENV | base64 --decode > .env
出力した環境変数の値(標準出力)を bash のパイプ機能を使用してデコード(base64 から復元)した後、.env
ファイルに出力しています。
リダイレクトやパイプなど初めて見た方は、bash 入門 というサイトに目を通しておくと良いかもしれません。
再びワークフローを実行語、Xserver に SSH 接続して本番環境の設定が記載された.env
ファイルが作成されていることを確認して下さい。
その後php artisan migrate
を実行して正常にデータベースと接続できることを確認して下さい。
注意点
Laravel の認証機能で Laravel Breeze をインストールした場合は npm コマンドでビルドする必要があります。
Xserver 側に Node.js をインストールして SSH 接続した後に npm を実行できるように環境を整えても良いのですが、めちゃくちゃ面倒なので出来るだけそんなことはしたくありません。
ワークフロー内で npm ビルドも実行出来るようにします。
ワークフローに Node.js をインストールする処理を追加する
actions/setup-node というアクションを使用してワークフロー内で使用する Node.js のバージョンを指定します。
その後、package.json
内のscripts
のコマンドを実行します。
name: deploy to production-xserver
on:
push:
branches: [main]
jobs:
deploy:
runs-on: ubuntu-latest
defaults:
run:
working-directory: ./src
steps:
- name: Setup PHP
uses: shivammathur/setup-php@v2
with:
php-version: "8.1.12"
- name: Checkout repository
uses: actions/checkout@v3
- name: Setting .env
env:
PRODUCTION_LARAVEL_ENV: ${{ secrets.PRODUCTION_LARAVEL_ENV }}
run: |
php -r "file_exists('.env') || copy('.env.example', '.env');"
echo $PRODUCTION_LARAVEL_ENV | base64 --decode > .env
- name: Composer Install
run: composer install -q --no-ansi --no-interaction --no-scripts --no-progress --prefer-dist
- name: Generate key
run: php artisan key:generate
- name: Directory Permissions
run: chmod -R 777 storage bootstrap/cache
+ - name: Use Node.js ${{ matrix.node-version }}
+ uses: actions/setup-node@v3
+ with:
+ node-version: 16.x # 開発環境のバージョンと合わせて下さい
+ - name: npm build
+ run: npm install && npm run build
- name: Deploy to Server
uses: burnett01/rsync-deployments@5.2.1
with:
switches: -avzr --delete
path: src/
remote_path: ${{ secrets.PRODUCTION_DEPLOY_REMOTE_PATH }}
remote_host: ${{ secrets.DEPLOY_HOST }}
remote_port: ${{ secrets.DEPLOY_PORT }}
remote_user: ${{ secrets.DEPLOY_USER }}
remote_key: ${{ secrets.DEPLOY_KEY }}
最後に
Github Actions を利用して Laravel を Xserver に自動デプロイする方法についてまとめました。今回は Xserver でしたが、SSH 接続出来るプランなら他のサーバでも利用可能だと思います。
その他、ワークフロー中に自動テストを走らせてテストが通らなければワークフロー中止したり、デプロイ後にマイグレーションコマンドを実行したりすることも出来ます。
今回の記事ではそこまで紹介していませんが、興味がある方は是非実践してみて下さい。