Dockerで開発したLaravelをGitHub Actionsでエックスサーバーに自動デプロイする手順

Dockerでローカル開発しているLaravelプロジェクトを、エックスサーバーの独自ドメインに公開し、mainブランチにpushしたら自動でデプロイされるようにする手順をまとめました。

実際に設定したときにつまずいた箇所も、最後に「つまずきポイント」としてエラーメッセージ付きでまとめています。

この記事の構成

  • Laravel本体はサーバーのホームディレクトリに配置します(公開ディレクトリの外なので、.env などが外から見えません)。
  • publicの中身だけを、ドメインのディレクトリ(public_html)にコピーします。
  • ビルドcomposer installnpm run build)はGitHub Actions上で行い、できたファイルをrsyncで転送します。サーバーにgitやNode.jsは不要です。
  • テストが通ったときだけデプロイします。

Dockerはローカル開発専用です。エックスサーバーではDockerは動かしません。

前提

  • エックスサーバーを契約済みで、公開するドメインを追加済み
  • LaravelプロジェクトをGitHubのリポジトリで管理している
  • ローカルはDocker(Docker Compose)で開発している
  • Laravel 11 / 12 を想定

記事中の値の読み替え

以下の値はご自分の環境に置き換えてください。

  • サーバーID:エックスサーバーのサーバーID
  • svXXXX.xserver.jp:サーバーパネル「サーバー情報」のホスト名
  • example.com:公開するドメイン
  • myapp:サーバーのホーム直下に置くLaravel本体のフォルダ名
  • /usr/bin/php8.3:サーバーで使うPHPのパス
  • app:docker-compose.yml のPHPコンテナのサービス名

全体像

リポジトリの構成

この記事では、Laravel本体が src フォルダに入っている構成で説明します。Laravelがリポジトリ直下にある場合の違いは、ワークフローの説明で補足します。

my-project/
├── .github/
│   └── workflows/
│       └── deploy.yml     ← 自動デプロイの設定
├── script/
│   └── deploy.sh          ← サーバー上で実行する処理
├── docker-compose.yml
├── docker/
└── src/                   ← Laravel本体

サーバー上の配置(完成形)

/home/サーバーID/
├── myapp/                     ← Laravel本体(src の中身)
│   ├── .env                   ← 最初に手動で作成。デプロイでは上書きしない
│   ├── storage/               ← 最初に手動で作成。デプロイでは上書きしない
│   ├── app/ vendor/ public/ ...
└── example.com/
    └── public_html/           ← myapp/public の中身をコピー
        ├── index.php          ← 読み込み先を ~/myapp に書き換え
        ├── .htaccess
        ├── build/
        └── storage → /home/サーバーID/myapp/storage/app/public

デプロイの流れ

  1. mainブランチにpush
  2. testジョブcomposer install → PHPUnitでテスト
  3. deployジョブ(テスト成功時のみ)
    1. composer install --no-devnpm run build でビルド
    2. SSHでサーバーに接続し、メンテナンスモードON
    3. rsyncで src の中身を ~/myapp に転送
    4. script/deploy.sh をサーバー上で実行(publicのコピー、index.phpの書き換え、キャッシュ作成、メンテナンスモードOFF)

1. ローカル側の準備

1-1. PHPのバージョンを揃える

エックスサーバーのサーバーパネルで使えるPHPバージョン(例:8.3)を確認し、DockerfileのPHPイメージも同じバージョンにします。

さらに、composer.lock が本番のPHPバージョンで解決されるように固定しておきます。

docker compose exec app composer config platform.php 8.3
docker compose exec app composer update --lock

1-2. package-lock.json をコミットする

GitHub Actionsの npm ci とキャッシュ設定には package-lock.json が必要です。src/package-lock.json がリポジトリに入っているか確認してください。

git ls-files src/package-lock.json

何も表示されない場合は作成します。PHPコンテナにはNode.jsが入っていないことが多いので、一時的にNodeのコンテナを使います。リポジトリ直下で実行してください。

docker run --rm -v "$PWD/src:/app" -w /app node:22 npm install

できた src/package-lock.json をコミットします。git add しても追加されない場合は、.gitignorepackage-lock.json が書かれていないか確認してください。

フロントエンドのビルド(Vite)を使っていない場合、この手順は不要です。Bladeファイルに @vite( がなければ使っていません。

1-3. テスト用のAPP_KEYを設定する

GitHub Actions上には .env がないため、そのままだとテストが No application encryption key has been specified. で失敗します。テスト専用のキーを生成して、phpunit.xml に書いておきます。

docker compose exec app php artisan key:generate --show

表示された値を src/phpunit.xml<php> の中に追加します。

<php>
    <env name="APP_ENV" value="testing"/>
    <env name="APP_KEY" value="base64:テスト用に生成した値"/>
    <!-- 以下は既存の設定 -->
</php>

phpunit.xml はGitにコミットされるので、本番のキーは使わず、必ずテスト用に別のキーを生成してください。--show を付けていればファイルは書き換わらないので、何度実行しても問題ありません。

テストでDBを使う場合は、phpunit.xml にコメントアウトされている DB_CONNECTION(sqlite)と DB_DATABASE(:memory:)の2行を有効にしておくと、Actions上でもDBなしで動きます。

1-4. 改行コードの設定(Windowsの場合)

Windowsで作ったシェルスクリプトは改行コードがCRLFになり、サーバーで $'\r': command not found というエラーになることがあります。リポジトリ直下に .gitattributes を作り、次の1行を書いておきます。

*.sh text eol=lf

2. エックスサーバー側の準備

2-1. ドメインとPHPの設定

サーバーパネルで次の3つを設定します。

  • ドメインを追加し、無料独自SSLを有効にする
  • 「PHP Ver.切替」で、ドメインのPHPバージョンをローカルと同じにする
  • 「SSH設定」でSSHをONにする

2-2. デプロイ用のSSH鍵を作る

SSH鍵の「向き」を整理する

SSH鍵は「どこからどこへ接続するか」で役割が変わります。混同しやすいので、先に整理しておきます。

  • 自分のPC → サーバー:ターミナルからログインするための鍵
  • サーバー → GitHub:サーバー上で git pull するための鍵(GitHubの「Deploy keys」に登録するもの)
  • GitHub Actions → サーバー:今回必要な鍵。秘密鍵をGitHubのSecretsに入れ、公開鍵をサーバーに登録します

他のプロジェクトですでにサーバーにログインできていても、多くの場合それは「自分のPC → サーバー」の鍵です。自分用の鍵をGitHubに預けるのは避け、デプロイ専用の鍵を新しく作るのがおすすめです。

鍵を作成する

パスフレーズを聞かれたら、何も入力せずにEnterを2回押します(GitHub Actionsから使うため、パスフレーズなしにします)。

Windows(PowerShell)の場合:

New-Item -ItemType Directory -Force "$env:USERPROFILE\.ssh"
ssh-keygen -t ed25519 -C "github-actions-deploy" -f "$env:USERPROFILE\.ssh\xserver_deploy"

PowerShellでは ~/.ssh/... と書くとホームフォルダに変換されず、保存に失敗します。$env:USERPROFILE を使ってください。

Mac / Linuxの場合:

ssh-keygen -t ed25519 -C "github-actions-deploy" -f ~/.ssh/xserver_deploy

xserver_deploy(秘密鍵)と xserver_deploy.pub(公開鍵)の2つのファイルができます。

公開鍵をサーバーに登録する

すでにSSHでログインできる場合は、サーバーパネルの「公開鍵登録・更新」は使わず、既存の鍵でログインして authorized_keys に追記します。パネルから登録すると、今使っている鍵が上書きされてログインできなくなるおそれがあります。

Windows(PowerShell)の場合:

Get-Content "$env:USERPROFILE\.ssh\xserver_deploy.pub" | ssh -i "$env:USERPROFILE\.ssh\既存の鍵ファイル" -p 10022 サーバーID@svXXXX.xserver.jp "cp ~/.ssh/authorized_keys ~/.ssh/authorized_keys.bak && (echo; tr -d '\r') >> ~/.ssh/authorized_keys"

Mac / Linuxの場合:

ssh -i ~/.ssh/既存の鍵ファイル -p 10022 サーバーID@svXXXX.xserver.jp "cp ~/.ssh/authorized_keys ~/.ssh/authorized_keys.bak && (echo; tr -d '\r') >> ~/.ssh/authorized_keys" < ~/.ssh/xserver_deploy.pub

このコマンドは、既存の authorized_keys をバックアップしてから、空行と新しい公開鍵を追記します。空行を入れているのは、既存ファイルの末尾に改行がないと、新しい鍵が前の行にくっついて両方使えなくなるためです。

まだSSHの鍵を登録していない場合は、サーバーパネルの「SSH設定」→「公開鍵登録・更新」に xserver_deploy.pub の中身を貼り付けて登録します。

新しい鍵でログインできるか確認する

-o IdentitiesOnly=yes を付けて、既存の鍵が使われないようにして確認します。

ssh -i "$env:USERPROFILE\.ssh\xserver_deploy" -o IdentitiesOnly=yes -p 10022 サーバーID@svXXXX.xserver.jp

既存の鍵でのログインも、引き続きできるか確認しておきましょう。

2-3. PHP CLIのパスを確認する

SSHでログインした状態で、使えるPHPを確認します。

ls /usr/bin/php*
/usr/bin/php8.3 -v

エックスサーバーでは php とだけ打つと、ドメインの設定とは違うバージョンが動くことがあります。デプロイでは必ずフルパス(例:/usr/bin/php8.3)を使います。

2-4. Laravel本体のフォルダ、storage、.envを作る

.envstorage はデプロイで上書きしないため、最初に手動で作成します。

ここで作るフォルダ名(myapp)は、後でワークフローに設定する DEPLOY_DIR と必ず同じにしてください。 ずれていると、デプロイ先に .env がなくてエラーになります。

mkdir -p ~/myapp/storage/{app/public,framework/{cache/data,sessions,views},logs}
mkdir -p ~/myapp/bootstrap/cache

本番用のAPP_KEYを生成します(ローカルで実行し、表示された値を控えます)。

docker compose exec app php artisan key:generate --show

サーバーで .env を作ります。viエディタに慣れていない場合は、cat > ... << 'EOF' から最後の EOF までを、値を書き換えてからまとめて貼り付けて実行すると作成できます。

cat > ~/myapp/.env << 'EOF'
APP_NAME=MyApp
APP_ENV=production
APP_KEY=base64:本番用に生成した値
APP_DEBUG=false
APP_URL=https://example.com

LOG_CHANNEL=daily
LOG_LEVEL=error

SESSION_DRIVER=file
CACHE_STORE=file
QUEUE_CONNECTION=sync
EOF

chmod 600 ~/myapp/.env
cat ~/myapp/.env

DBを使わない場合は、上の例のように SESSION_DRIVERCACHE_STOREQUEUE_CONNECTION を必ず設定してください。Laravel 11以降は初期設定でこれらの保存先がデータベースになっており、DBがないとキャッシュ削除やページ表示でエラーになります。

DBを使う場合は、サーバーパネルの「MySQL設定」でデータベースとユーザーを作成し、次の設定を追加します。データベース名とユーザー名にはサーバーIDの接頭辞が付きます。セッションなどの保存先をDBにしたい場合は、上の3行を database にしても構いません。

DB_CONNECTION=mysql
DB_HOST=サーバーパネルに表示されたホスト名
DB_PORT=3306
DB_DATABASE=サーバーID_dbname
DB_USERNAME=サーバーID_user
DB_PASSWORD=パスワード

2-5. 初期ファイルを削除する

ドメイン追加時に置かれる index.html が残っていると、index.php より優先して表示されます。削除しておきます。

rm -f ~/example.com/public_html/index.html

3. GitHub Secretsを登録する

リポジトリの「Settings」→「Secrets and variables」→「Actions」で、次の4つを登録します。

  • XSERVER_SSH_KEYxserver_deploy.pub が付いていない方)の中身をすべて
  • XSERVER_HOSTsvXXXX.xserver.jp
  • XSERVER_USER:サーバーID
  • XSERVER_SSH_PORT10022

秘密鍵は -----BEGIN OPENSSH PRIVATE KEY----- から -----END OPENSSH PRIVATE KEY----- まで丸ごと貼り付けます。次のコマンドでクリップボードにコピーできます。

Windows(PowerShell):

Get-Content "$env:USERPROFILE\.ssh\xserver_deploy" -Raw | Set-Clipboard

Mac:

pbcopy < ~/.ssh/xserver_deploy

XSERVER_SSH_KEY に入れるのはデプロイ用に作った鍵です。普段ログインに使っている鍵ではありません。


4. デプロイスクリプトを作る(script/deploy.sh)

リポジトリ直下の script/deploy.sh に作成します。サーバー固有の値はワークフローから受け取るので、このファイルは書き換えずにそのまま使えます。

#!/bin/bash
set -euo pipefail

# ワークフローから受け取る値
APP_DIR="$HOME/${DEPLOY_DIR:?DEPLOY_DIR が指定されていません}"
PUBLIC_DIR="$HOME/${DEPLOY_DOMAIN:?DEPLOY_DOMAIN が指定されていません}/public_html"
PHP="${PHP_BIN:?PHP_BIN が指定されていません}"

cd "$APP_DIR"

echo "==> public の中身をドメインディレクトリへコピー"
rsync -a --delete \
  --exclude='.user.ini' \
  --exclude='.well-known/' \
  --exclude='/storage' \
  "$APP_DIR/public/" "$PUBLIC_DIR/"

echo "==> index.php の読み込み先を Laravel 本体に向ける"
# __DIR__.'/../vendor/autoload.php' → '/home/サーバーID/myapp/vendor/autoload.php'
sed -i "s#__DIR__.'/..#'${APP_DIR}#g" "$PUBLIC_DIR/index.php"

echo "==> storage のシンボリックリンク"
ln -sfn "$APP_DIR/storage/app/public" "$PUBLIC_DIR/storage"

if [ "${RUN_MIGRATIONS:-false}" = "true" ]; then
  echo "==> マイグレーション"
  "$PHP" artisan migrate --force --no-interaction
fi

echo "==> キャッシュ"
"$PHP" artisan optimize:clear
"$PHP" artisan config:cache
"$PHP" artisan route:cache
"$PHP" artisan view:cache

"$PHP" artisan up
echo "==> デプロイ完了"

スクリプトのポイント

rsyncの除外設定--delete は、publicにないファイルを public_html から削除します。そのため、エックスサーバーのphp.ini設定が保存される .user.ini、SSL証明書の認証に使われる .well-known、ストレージのリンクを除外しています。ほかに public_html に残したいファイルがあれば --exclude を追加してください。

index.phpの書き換えpublic/index.php__DIR__.'/../vendor/...' のように「1つ上のフォルダ」を参照しています。public_html にコピーすると参照先がずれるので、Laravel本体の絶対パスに書き換えています。

storageのリンクphp artisan storage:link を実行すると、リンクが myapp/public 側に作られてしまいます。そのため lnpublic_html に直接作っています。

.htaccessについてpublic_html/.htaccess はLaravelの public/.htaccess で毎回上書きされます。サーバーパネルの機能で .htaccess に書き込まれる設定を使う場合は、その内容を public/.htaccess 側に書いてコミットしてください。


5. ワークフローを作る(.github/workflows/deploy.yml)

冒頭の env を自分の環境に合わせて書き換えます。

name: Deploy to Xserver

on:
  push:
    branches: [main]
  workflow_dispatch: {}   # Actionsタブから手動実行もできるようにする

# 連続でpushしたときにデプロイが同時に走らないようにする
concurrency:
  group: production-deploy
  cancel-in-progress: false

env:
  LARAVEL_DIR: src             # Laravel本体のフォルダ(リポジトリ直下なら ".")
  PHP_VERSION: '8.3'           # エックスサーバーと同じバージョン
  NODE_VERSION: '22'           # ローカルと同じバージョン
  DEPLOY_DIR: myapp            # サーバーのホーム直下のフォルダ名(2-4で作ったもの)
  DEPLOY_DOMAIN: example.com   # 公開するドメイン
  PHP_BIN: /usr/bin/php8.3     # サーバーのPHP CLI(フルパス)
  RUN_MIGRATIONS: 'false'      # DBを使うなら 'true'

jobs:
  test:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4

      - name: Setup PHP
        uses: shivammathur/setup-php@v2
        with:
          php-version: ${{ env.PHP_VERSION }}
          tools: composer:v2
          coverage: none

      - name: Composer install
        working-directory: ${{ env.LARAVEL_DIR }}
        run: composer install --no-interaction --prefer-dist

      - name: Run PHPUnit
        working-directory: ${{ env.LARAVEL_DIR }}
        run: ./vendor/bin/phpunit

  deploy:
    needs: test   # テストが成功したときだけデプロイする
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4

      - name: Setup PHP
        uses: shivammathur/setup-php@v2
        with:
          php-version: ${{ env.PHP_VERSION }}
          tools: composer:v2
          coverage: none

      - name: Composer install (production)
        working-directory: ${{ env.LARAVEL_DIR }}
        run: composer install --no-dev --no-interaction --prefer-dist --optimize-autoloader

      # ---- Viteを使っていない場合は、この2ステップを削除 ----
      - name: Setup Node
        uses: actions/setup-node@v4
        with:
          node-version: ${{ env.NODE_VERSION }}
          cache: npm
          cache-dependency-path: ${{ env.LARAVEL_DIR }}/package-lock.json

      - name: Build assets
        working-directory: ${{ env.LARAVEL_DIR }}
        run: |
          npm ci
          npm run build
      # ------------------------------------------------------

      - name: Configure SSH
        id: ssh
        run: |
          mkdir -p ~/.ssh
          echo "${{ secrets.XSERVER_SSH_KEY }}" > ~/.ssh/deploy_key
          chmod 600 ~/.ssh/deploy_key
          ssh-keyscan -p "${{ secrets.XSERVER_SSH_PORT }}" "${{ secrets.XSERVER_HOST }}" >> ~/.ssh/known_hosts
          cat >> ~/.ssh/config <<EOF
          Host xserver
            HostName ${{ secrets.XSERVER_HOST }}
            User ${{ secrets.XSERVER_USER }}
            Port ${{ secrets.XSERVER_SSH_PORT }}
            IdentityFile ~/.ssh/deploy_key
            IdentitiesOnly yes
          EOF

      - name: Maintenance mode ON
        run: ssh xserver "cd ~/$DEPLOY_DIR && $PHP_BIN artisan down --retry=60 || true"

      - name: Upload files
        run: |
          rsync -az --delete \
            --exclude='/.env' \
            --exclude='/storage/' \
            --exclude='/node_modules/' \
            --exclude='/tests/' \
            --exclude='/database/database.sqlite' \
            "./$LARAVEL_DIR/" "xserver:$DEPLOY_DIR/"

      - name: Run deploy script
        run: |
          tr -d '\r' < script/deploy.sh | ssh xserver \
            "DEPLOY_DIR='$DEPLOY_DIR' DEPLOY_DOMAIN='$DEPLOY_DOMAIN' PHP_BIN='$PHP_BIN' RUN_MIGRATIONS='$RUN_MIGRATIONS' bash -s"

      - name: Maintenance mode OFF (on failure)
        if: failure() && steps.ssh.outcome == 'success'
        run: ssh xserver "cd ~/$DEPLOY_DIR && $PHP_BIN artisan up || true"

      - name: Clean up SSH key
        if: always()
        run: rm -f ~/.ssh/deploy_key

ワークフローのポイント

転送されるのは src の中身だけ:rsyncの転送元が ./src/ なので、リポジトリ直下のDocker関連ファイルや script フォルダはサーバーに送られません。そのため deploy.sh はサーバーに置かず、bash -s でスクリプトの中身を送り込んで実行しています。tr -d '\r' でWindowsの改行コードも取り除いています。

サーバーの .env と storage は消えない:rsyncで --exclude したパスは、--delete の削除対象にもなりません。

パスはホームからの相対パスDEPLOY_DIR~ 基準で扱うので、ワークフローにサーバーIDを書く必要がありません。

Laravelがリポジトリ直下にある場合LARAVEL_DIR"." にし、Upload filesのrsyncに --exclude='/.git/'--exclude='/.github/'--exclude='/script/'、Docker関連ファイルの除外を追加してください。

テストでViewを表示している場合:テストが Vite manifest not found で失敗するときは、testジョブにもSetup NodeとBuild assetsのステップを追加するか、テスト内で $this->withoutVite() を呼んでください。


6. 初回デプロイと確認

script/deploy.sh.github/workflows/deploy.ymlphpunit.xml.gitattributes などの変更をコミットしてmainにpushします。

GitHubの「Actions」タブで testdeploy の両方に緑のチェックが付けば成功です。「Run deploy script」のログに ==> デプロイ完了 と出ていることも確認しましょう。

サーバーでは、次のコマンドで配置を確認できます。

grep require ~/example.com/public_html/index.php   # パスが /home/サーバーID/myapp/... になっている
ls -la ~/example.com/public_html/storage           # シンボリックリンクがある

最後に https://example.com にアクセスして、ページが表示されれば完了です。

スケジューラーを使う場合

サーバーパネルの「Cron設定」で、毎分実行するコマンドを登録します。

/usr/bin/php8.3 /home/サーバーID/myapp/artisan schedule:run >> /dev/null 2>&1

.env を変更したとき

config:cache 済みの環境では、.env を編集しただけでは反映されません。次のデプロイ時に反映されますが、すぐ反映したい場合はサーバーで実行します。

cd ~/myapp && /usr/bin/php8.3 artisan config:cache

つまずきポイントまとめ

実際に設定したときに遭遇したエラーと、その原因・対処です。

ssh-keygenで「Saving key “~/.ssh/xserver_deploy” failed: No such file or directory」

原因:PowerShellでは、ssh-keygen に渡した ~ がホームフォルダに変換されません。

対処-f "$env:USERPROFILE\.ssh\xserver_deploy" のようにパスを指定します(2-2を参照)。

どのSSH鍵を使えばいいのかわからない

原因:「PCからログインする鍵」「サーバーからGitHubに接続する鍵」「GitHub Actionsからサーバーに接続する鍵」は、それぞれ別物です。

対処:GitHub Actions用の鍵を新しく作り、登録作業のためのログインには既存の鍵を使います。パネルからの公開鍵登録は既存の鍵を上書きするおそれがあるので、ログインできる場合は authorized_keys に追記します(2-2を参照)。

テストが「MissingAppKeyException: No application encryption key has been specified.」で失敗する

原因.env はGitにコミットされないので、GitHub Actions上ではAPP_KEYが空です。

対処:テスト用に生成したキーを phpunit.xml に書きます。本番のキーは使いません(1-3を参照)。

テストが×で、デプロイも実行されない

原因:deployジョブに needs: test があるため、テストが失敗するとデプロイはスキップされます。意図どおりの動作です。

対処:先にテストを通します。Laravelのスターターキットから作ったプロジェクトでは、tests.yml などのワークフローが最初から入っていることがあります。不要なら削除し、ワークフローが重複していないかも確認してください。

「Error: Some specified paths were not resolved, unable to cache dependencies.」

原因cache-dependency-path で指定した package-lock.json がリポジトリにありません。

対処package-lock.json を作成してコミットします。Viteを使っていなければ、Setup NodeとBuild assetsのステップを削除します(1-2を参照)。

npm installで「exec: “npm”: executable file not found in $PATH」

原因:PHPコンテナにNode.jsが入っていません。

対処:Node用のサービスがあればそちらで実行し、なければ docker run --rm -v "$PWD/src:/app" -w /app node:22 npm install で一時的なコンテナを使います。package.json がないのに npm install を実行すると空の package.json ができるので、先に存在を確認してください。

「ssh: Could not resolve hostname xserver」

原因:SSHの設定より前のステップで失敗し、失敗時のメンテナンス解除ステップが xserver という接続先を知らないまま実行されました。本当の原因はその前のエラーです。

対処:ログを上にさかのぼって最初のエラーを確認します。失敗時のステップに if: failure() && steps.ssh.outcome == 'success' を付けておくと、このエラー自体が出なくなります。

「bash: …/script/deploy.sh: No such file or directory」

原因:rsyncで転送するのは src の中身だけなので、src の外にある script/deploy.sh はサーバーに存在しません。scriptsscript のようなフォルダ名の違いでも起きます。

対処:サーバー上のファイルを実行するのではなく、tr -d '\r' < script/deploy.sh | ssh xserver "... bash -s" でActions側からスクリプトを送り込みます(5を参照)。GitHubの画面ではSecretsの値が *** と伏せて表示されるので、パスの確認はファイル一覧(git ls-files "*deploy.sh")で行うと確実です。

デプロイは成功するのに500エラーになる

原因.envstorage を作ったフォルダと、実際のデプロイ先のフォルダが違っていることがあります。rsyncは .envstorage を転送しないので、デプロイ先にこれらがないとエラーになります。

対処ls -la ~/myapp.envstorage があるか確認します。原因を調べるときは、~/myapp/storage/logs/ のログを見ます。

DBを使っていないのにSQLSTATEエラーが出る

原因:Laravel 11以降は、セッション・キャッシュ・キューの保存先が初期設定でデータベースです。

対処.envSESSION_DRIVER=fileCACHE_STORE=fileQUEUE_CONNECTION=sync を設定します(2-4を参照)。

「$’\r’: command not found」

原因:Windowsで作ったシェルスクリプトの改行コードがCRLFです。

対処.gitattributes*.sh text eol=lf を書きます。この記事のワークフローでは tr -d '\r' でも取り除いています。

「Node 20 is being deprecated」という警告が出る

原因:GitHub Actionsのアクション自体が動くNode.jsのバージョンについての警告です。

対処:デプロイの成否には影響しません。気になる場合は、actions/checkoutactions/setup-node を新しいメジャーバージョンに上げてください(各アクションのREADMEで変更点を確認してから上げるのがおすすめです)。

viエディタの操作がわからない

vi で開いた直後は文字を入力できません。i で入力モードにし、編集が終わったら Esc:wqEnter で保存して終了します。保存せずに抜けるときは Esc:q!Enter です。この記事の2-4のように、cat > ファイル << 'EOF' で作成すればviを使わずに済みます。


おわりに

この構成にすると、サーバーにgitやNode.jsを入れずに、mainへのpushだけでテストからデプロイまで自動化できます。.envstorage はサーバー上に残り続けるので、デプロイのたびに設定やアップロードファイルが消える心配もありません。

エックスサーバーのようなレンタルサーバーでも、GitHub Actionsでビルドしてから転送する形にすれば、Laravelを快適に運用できます。

VIEW ALL POSTS