開発ブログ

株式会社Nextatのスタッフがお送りする技術コラムメインのブログ。

電話でのお問合わせ 075-744-6842 ([月]-[金] 10:00〜17:00)

  1. top >
  2. 開発ブログ >
  3. PHP >
  4. Laravel >
  5. Cloud Native Buildpacksとheroku/builder:22でLaravelアプリのコンテナイメージを作成する

Cloud Native Buildpacksとheroku/builder:22でLaravelアプリのコンテナイメージを作成する

こんにちは、ナカエです。

桜の開花とともに初夏のような暖かさがやってきましたね。

弊社ではAWS App Runnerで動かしている社内用のLaravelアプリケーションがあります。

そちらで利用するコンテナイメージのビルドにはCloud Native Buildpacksを用いているのですが、先日ビルダーイメージとして用いていた heroku/buildpacks:20 のサポートが終了している ことに気づきました。

新しいビルダーイメージ heroku/builder:22 を利用する場合は以前の設定を少し変更する必要があり、本記事の内容はそちらの覚書になります。

検証環境とソフトウェアのバージョン

  • OS: macOS 14.4.1 (Sonoma)
  • CPU: Apple M1 Max
  • zsh 5.9
  • pack 0.33.2
  • PHP 8.3.4(ホストマシン)8.2.2(ビルドするコンテナ)
  • Node.js 20.12.2 (ホストマシン・コンテナ双方)
  • Laravel 11.0.6

Laravelアプリを作成

下記コマンドで新規Laravelアプリを作成します。

composer create-project laravel/laravel laravel-heroku-builder-22

手元ではLaravel 11.0.6で作成されました。

Cloud Native Buildpacks向けのイメージビルド設定

作成・変更するファイルは 以前のApp Runner + Cloud Native Buildpacksの記事 と同じですが、一部内容が異なります。

Procfile

PHP実行環境の起動について指定するProcfileは変更なしです。nginx + PHP-FPM 構成で動かします。

web: heroku-php-nginx -C nginx.conf public

nginx.conf

locationの設定は同じですが、一時ファイルを保存するのにデフォルトの設定だとApp Runnerのコンテナ起動時にエラーが出たので、/tmp以下に変更しています。

location / {
    try_files $uri @rewriteapp;
}

location @rewriteapp {
    rewrite ^(.*)$ /index.php$1 last;
}

client_body_temp_path /tmp/client_body_temp;
proxy_temp_path /tmp/proxy_temp;
fastcgi_temp_path /tmp/fastcgi_temp;
uwsgi_temp_path /tmp/uwsgi_temp;
scgi_temp_path /tmp/scgi_temp;

project.toml

project.tomlはスキーマをバージョン0.2としているので一部書式が変わっていますが、builderを heroku/builder:22 に変更しているのが主な違いです

[_]
id = "laravel-heroku-builder-22"
name = "Laravel + heroku/builder:22"
version = "1.0.0"
schema-version="0.2"

[io.buildpacks]
builder = "heroku/builder:22"
exclude = [
    ".idea",
    "/README.md",
    ".git",
    "/vendor",
    "/node_modules",
    "/bootstrap/cache/*.php",
]
[[io.buildpacks.group]]
uri = "heroku/php"
[[io.buildpacks.group]]
uri = "heroku/procfile"
[[io.buildpacks.group]]
uri = "heroku/nodejs"

[[io.buildpacks.build.env]]
name = "NODE_ENV"
value = "production"

composer.json

直接編集すると composer.lock に反映されないので、composerコマンドで設定します。

HerokuのBuildpackはcomposer.jsonを読み込んで自動的にPHP拡張を設定が可能です。 ここではext-pdoとext-pdo_sqliteを指定します。

composer require ext-pdo
composer require ext-pdo_sqlite

差分は下記のようになります

{
    // 
    "require": {
        "php": "^8.2",
+       "ext-pdo": "*",
+       "ext-pdo_sqlite": "*",
        "laravel/framework": "^11.0",
        "laravel/tinker": "^2.9"
    },
    // 
    "config": {
        "optimize-autoloader": true,
        "preferred-install": "dist",
        "sort-packages": true,
        "allow-plugins": {
            "pestphp/pest-plugin": true,
            "php-http/discovery": true
        }
    },
    // 
}

package.json

Node.jsの20系が使えるようになっているのでそちらを指定しています。

{
+   "name": "laravel-heroku-builder-22",
    "private": true,
+   "engines": {
+       "node": "20.x"
+   },
    "scripts": {
        "dev": "vite",
        "build": "vite build"
    },
    "devDependencies": {
        "axios": "^1.6.4",
        "laravel-vite-plugin": "^1.0",
        "vite": "^5.0"
    }
}

Node.jsのパッケージマネージャーを決定するのにロックファイルが利用されるため、一度パッケージをインストールしておきます。 pnpmとYarnも選択できますが、今回はnpmを使います。

npm install

パッケージがnode_modulesに配置され、package-lock.jsonが生成されます。

コンテナイメージのビルドとコンテナ実行

pack CLIを使ってビルドします。

まだ導入していない場合はHomeBrewを使ってインストールします。

brew install buildpacks/tap/pack

インストールできたらプロジェクトのルートで下記のコマンドを実行します。

pack build laravel-heroku-builder-22

laravel-heroku-builder-22という名前のコンテナイメージが作成されます。

このイメージを下にコンテナを起動するコマンドが下記です。 ビルドしたコンテナイメージはlinux/amd64向けですが、ホストマシンがM1 Macなのでplatformオプションを明示的に指定しています。

docker run --rm -e PORT=8080 -p 8080:8080 --platform linux/amd64 laravel-heroku-builder-22

http://localhost:8080 にアクセスすると、Laravelのホーム画面が表示されます。

laravel-heroku-builder-22.png
 

まとめ

一部仕様が変わってはいますが、Herokuのビルダーイメージを使うと相変わらず少ない手数でコンテナイメージが作成できるので重宝しています。ただ、PHP 8.3に早めに対応してもらえるとより嬉しいですね。

TOPに戻る