Sailのbuildスクリプトを理解する

Laravel Sailのbulidスクリプトを理解する Webアプリ開発

本記事を読むことでSailでLaravelプロジェクトを作成する際にどのようなことが行われているかが理解できます。Sailの裏側ではDockerが使用されています。普段Dockerを触らない人でも理解できるようDocker初心者の僕自身理解できるようまとめました。ご参考ください。

Sailのbuildスクリプトを理解しようと思った経緯

自宅環境ではSailを使って簡単にLaravelアプリ(プロジェクト)を作成できました。
しかし、会社環境では、同じやり方で作成できませんでした。
エラーがどの段階で起きているのか、コマンドを叩いただけではわからなかったため、コマンドの中で何を実施しているかを理解しようと思いました。

エラーの解決策は本記事では記載しません。解決策をお探しの方は、時間に余裕があるなら、近日、解決策もまとめる予定のため、お待ちください。

Sailのbuildスクリプトを理解する

Sailのbuildスクリプトとは?

本記事で扱う「Sailのbuildスクリプト」とは、Laravelプロジェクトを作成する際に使用する下記コマンドでcurlで取得し、bashに渡しているスクリプトのことです。

curl -s https://laravel.build/example-app | bash

curlに渡しているURLにブラウザでアクセスするとわかるのですが、curlでは下記スクリプトを取得しているだけです。
このスクリプトのことを今回の記事では「Sailのbuildスクリプト」と呼んでいます。

docker info > /dev/null 2>&1

# Ensure that Docker is running...
if [ $? -ne 0 ]; then
    echo "Docker is not running."

    exit 1
fi

docker run --rm \
    --pull=always \
    -v "$(pwd)":/opt \
    -w /opt \
    laravelsail/php82-composer:latest \
    bash -c "laravel new example-app && cd example-app && php ./artisan sail:install --with=mysql,redis,meilisearch,mailpit,selenium "

cd example-app

# Allow build with no additional services..
if [ "mysql redis meilisearch mailpit selenium" == "none" ]; then
    ./vendor/bin/sail build
else
    ./vendor/bin/sail pull mysql redis meilisearch mailpit selenium
    ./vendor/bin/sail build
fi

CYAN='\033[0;36m'
LIGHT_CYAN='\033[1;36m'
BOLD='\033[1m'
NC='\033[0m'

echo ""

if sudo -n true 2>/dev/null; then
    sudo chown -R $USER: .
    echo -e "${BOLD}Get started with:${NC} cd example-app && ./vendor/bin/sail up"
else
    echo -e "${BOLD}Please provide your password so we can make some final adjustments to your application's permissions.${NC}"
    echo ""
    sudo chown -R $USER: .
    echo ""
    echo -e "${BOLD}Thank you! We hope you build something incredible. Dive in with:${NC} cd example-app && ./vendor/bin/sail up"
fi

次のセクションからこのスクリプトのブロックごとに理解していきたいと思います。

1つ目のブロック:Dockerの起動確認

下記1つ目のブロックでは、Dockerが起動しているか確認しています。

docker info > /dev/null 2>&1

# Ensure that Docker is running...
if [ $? -ne 0 ]; then
    echo "Docker is not running."

    exit 1
fi

1行目のdocker infoコマンドはDockerがインストールされていれば、正常終了(終了コード0)で終了します。
このスクリプトのユーザーはdocker infoコマンドの標準出力および例外出力に興味ないので、「/dev/null」に出力するようにしているようです。「/dev/null」は、出力先に選んでも何も起きないファイルです。

4行目でdocker infoコマンドの終了コードを確認しています。
コマンドでエラーが起きた場合は、「Docker is not running.」が標準出力し、スクリプトがエラー終了します。
ここでエラー終了した時はDockerのインストール、または、設定を見直す必要があります。

2つ目のブロック:SailコンテナでのLaravelプロジェクトの作成

下記2つ目のブロックでは、Sailコンテナを作成および起動し、Laravelプロジェクトを作成しています。前記事でSail(Docker)と表記した理由が2ブロック目に現れています。docker を使用して環境を作っているため、括弧づけでDockerと表現しました。このセクションでは、主に1-6行目から成るコマンドとオプションの意味を解説します。

docker run --rm \
    --pull=always \
    -v "$(pwd)":/opt \
    -w /opt \
    laravelsail/php82-composer:latest \
    bash -c "laravel new example-app && cd example-app && php ./artisan sail:install --with=mysql,redis,meilisearch,mailpit,selenium "

cd example-app

1行目の docker run は、コンテナをDockerイメージから作成し、起動するコマンドです。docker run コマンドは下記のような構成になります。そのため、上記のコマンドでは、1-4行目がオプション、5行目がイメージ、6行目がコマンドとその引数たちとなります。

docker run [オプション] イメージ [コマンド] [引数...]

1行目の--rmオプションは同じコンテナが既に存在している場合、そのコンテナを削除するオプションです。

2行目の--pullオプションは、コンテナを作成または起動する前にイメージをプルするかを決めるオプションです。ここではalwaysのため、毎回イメージをぷるして最新のイメージを使うことになっています。
--pullオプションでは、他にmissing, neverがあります。missingは、イメージのキャッシュが見つからない/使えいない場合にイメージをプルします。neverもイメージのキャッシュを基本使用し、見つからない/使えない場合は、イメージをプルせずにコンテナの作成に失敗します。

3行目の-vオプションは、コンテナとローカルのボリューム(ストレージ領域)をリンク付けけるオプションです。"$(pwd)":/optで、"$(pwd)"(現在のディレクトリ)をコンテナ内の/optディレクトリにリンク付けています。

4行目の-wオプションは、コンテナ内でのワーキングディレクトリを決めるオプションです。 値が/optとなっているため、先ほど指定したディレクトリがワーキングディレクトリとなります。

5行目のlaravelsail/php82-composer:latestは、作成するコンテナのイメージになります。イメージの詳細は、Docker Hubで確認できます。
イメージの詳細ページのIMAGE LAYERSを確認するとコンテナ内で何を行っているかがわかりました。
詳細は省きますが、最新のイメージでもdockerを使ってPHPの実行環境を作ってGitHubにあるLaravel Installerを実行して、Laravelプロジェクトを作成しているようです。

6行目は、コンテナ内で実行されるコマンドです。
laravel new example-appは、新しいLaravelプロジェクトを作るコマンドです。
cd testで作成したプロジェクトのディレクトリに移動しています。
php ./artisan sail:install --with=mysql,redis,meilisearch,mailpit,seleniumでsailを使用して、必要なサービスをインストールしています。

3つ目のブロック:追加サービスのビルド方法

下記3つ目のブロックでは、特定の追加サービスの(MySQL、Redis、Meilisearch、Mailpit、Selenium)の有無に基づいてビルドの方法を制御しています。

# Allow build with no additional services..
if [ "mysql redis meilisearch mailpit selenium" == "none" ]; then
    ./vendor/bin/sail build
else
    ./vendor/bin/sail pull mysql redis meilisearch mailpit selenium
    ./vendor/bin/sail build
fi

4つ目のブロック:ターミナルの表示設定

4つ目のブロックでは、ターミナルに表示されるテキストの色とスタイルを設定するための変数を定義しています。

CYAN='\033[0;36m'
LIGHT_CYAN='\033[1;36m'
BOLD='\033[1m'
NC='\033[0m'

echo ""

5つ目のブロック:プロジェクトへの権限付与

下記5つ目のブロックでは、作成したプロジェクトの権限を現在のユーザーに付与しています。

if sudo -n true 2>/dev/null; then
    sudo chown -R $USER: .
    echo -e "${BOLD}Get started with:${NC} cd example-app && ./vendor/bin/sail up"
else
    echo -e "${BOLD}Please provide your password so we can make some final adjustments to your application's permissions.${NC}"
    echo ""
    sudo chown -R $USER: .
    echo ""
    echo -e "${BOLD}Thank you! We hope you build something incredible. Dive in with:${NC} cd example-app && ./vendor/bin/sail up"
fi

以上で、全ブロックの説明を終わります。
開発環境の構築では、2ブロック目で行っているプロジェクトが肝となりそうです。curlで行わずに、一旦ローカルにスクリプトを出力してから、オプションを変えると自分の環境や要求に合ったdockerを起動させられます。

感想

会社で環境構築をやった際に詰まりまくったおかげで、Laravelのbuildスクリプトの中身を勉強するいいきっかけになりました。
Sailを使いこなすにはDockerの勉強がまだま必要そうなので、理解できたことをまた記事にしたいと思います。

コメント

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