メシのタネ

メシのタネになる、Laravelや設計思想の技術配信サイト


さらば phpenv──🍺 Brew と 🐳 Docker で PHP バージョン管理が秒で終わった話


  1. 開発環境
  2. さらば phpenv──🍺 Brew と 🐳 Docker で PHP バージョン管理が秒で終わった話

nodeenvが便利だからphpにもそう言うツールがないかなと思って、調べたらphpenvなるものがあったので、

多分便利なんだろうなと、ずっとphpenv使って来てたんだけど、brewでインストールしたら秒で済んだ。

brew install php@8.2

よく調べてみたら、結局ローカルにパッケージ見にいくから、そのパッケージにパスを通してやる必要があるのだ。

たとえばこういうの探しにいく 👉(OpenSSL / libzip / ICU / Oniguruma

存在しないとエラーになるので、zshrcとかにpathを追加する羽目になる。超めんどい。

だったら最初から「PHP 本体も Brew」、
旧版使いたいならは Docker 使えばいいし。ってなりました。

関係ないけどonigurumaの作者は日本人。

repositoryここ → https://github.com/kkos/oniguruma

正規表現に日本語使うPHPerは足を向けて寝ないように。

👹 深淵で黙々と「鬼車」を磨き続ける K. Kosakoに感謝

なぜ Node はバージョン管理ツール(nodeenv)と相性がいいのか?

「配布方式がバイナリ完結で、依存がほぼゼロ」
そのおかげでnodeenvと組み合わせたときに切り替えが爆速になる。

🍱 公式が「OS 別プリビルド」を用意してくれる

言語配布形態インストール工程
NodemacOS/Linux/Windows 向け tar/zip の実行バイナリ展開→パスを通すだけ
PHPフルソース が原則
(tar.gz + configure && make)
依存探索→コンパイル→インストール

Node は展開直後から node npm が即起動。
nodenv install 20.11.1実体を DL → 解凍 → シム更新 で終わるのはこのため。

たねまる

シムは(shim) 「かませ木」ってことらしいね〜。シム更新については後述するからね。

🛠️ OS 依存ライブラリがほぼ要らない

  • Node 本体は 内部に V8+必要なネイティブ依存を同梱
  • OpenSSL すらバイナリに静的リンクされているので、ホスト側のパッケージと衝突しない。
  • 結果:brew upgrade openssl でビルドし直し…という 二次作業ゼロ

⚡️「切り替え=シム書き換え」なので所要ミリ秒

~/.nodenv/shims/node  →  /Users/you/.nodenv/versions/18.19.1/bin/node
                        /Users/you/.nodenv/versions/20.11.1/bin/node
  • nodenv は シム(薄いラッパースクリプト) のリンク先を変えるだけ。
  • 実ファイルのコピーや再コンパイルは発生せず、シェル一瞬で反映。
  • npm/pnpm のグローバルパッケージも「バージョンごとの sandbox」に閉じ込められるため衝突しにくい。

👥 開発フローが「複数 Node 前提」で回る

  • LTS ↔︎ Current の差分確認が 月イチレベルで必要。
  • フロント系ライブラリは「Node 18 サポート終了、20 必須へ」みたいな移行が早い。
  • CI(GitHub Actions)は actions/setup-node@v4 一発で同バージョンを引ける。

バージョンを気軽に変えられる価値が高い文化だから、envツールの秒切り替えが真価を発揮する。

🐘 なぜ「phpenv は nodenv ほど手軽じゃない」のか?

ワンコマンドで済まない摩擦が多いから。

🛑 手間が発生する所Node (nodenv)PHP (phpenv)
インストール🍱 プリビルドをDLして展開 → 10 秒🛠 ソース+依存解決+コンパイル → 数分〜10分
依存ライブラリほぼ同梱(V8・OpenSSL も静的リンク)brew install openssl libzip icu4c oniguruma … を先に用意
切り替えシムのリンク先を書き換えるだけ ⚡️まずビルド → その後シム更新 ※ここで時間差
実行系の一貫性CLI = ランタイム1本phpenvは CLIのみ切替、FPMは別ビルドになる事が多い
アップデート対応nodenv install 20.x → 即完依存を更新したら 各バージョンを再ビルド

🧩 結果的に:

  • Node は「DLして symlink 張り替え」で完了=手数ゼロ感
  • PHP は「事前準備+ビルド+環境差分調整」で摩擦が多い

👉 上記の理由から今回の解決案

シーンベストな運用
Macで最新 8.2+ だけ🍺 Homebrewbrew install php@8.2 → 10 秒完了
旧版や複数OS検証🐳 Dockerphp:7.4-fpm-alpine などで完全隔離

💡 手軽さを nodenv 並みに近づけつつ、レガシーメンテにも対応できる。

🍺 Homebrew で PHP を“一撃管理”する(Mac 専用レシピ)

ゴール

  • brew install php@8.2 だけで CLI と FPM をそろえる
  • 旧版も数秒で切り替えられる――nodenv に近い手軽さを Mac で実現する

🕰️ まずは現行 LTS を入れてみる

# 公式ボトルは 8.2 がデフォルト
brew install php@8.2
brew link --overwrite --force php@8.2   # CLI & FPM を同一パスに固定
php -v                                   # → PHP 8.2.x
  • 10 秒で完了。依存ライブラリはボトルにリンク済み
  • php-fpm も同じ Cellar を指すので CLI ≡ FPM ねじれゼロ
  • Homebrew 版はデフォルトで pear 無効・opcache 有効と良い感じの設定

🔄 別のPHPのバージョンを指定する

brew tap shivammathur/php               # 旧版・開発版が豊富
brew install shivammathur/php/php@8.4   # 8.4-dev でも可

インストール→リンク切替は1行ずつ:

# 8.4 を有効化
brew link --overwrite --force shivammathur/php/php@8.4
php -v   # → PHP 8.4.x

# 8.2 に戻す
brew link --overwrite --force php@8.2

所要:数秒。nodenv の ln -s に近い感覚。

アップデートもワンコマンド

brew update
brew upgrade php@8.2
  • 拡張モジュール(intl, redis など)も自動で再リンク
  • CI とそろえるときは shivammathur/setup-php で同じ 8.2 を指定するだけ

🏁 まとめ:Mac なら Brew、一発で nodenv 並みの快適さ

  • プリビルド+リンク切替ほぼ “秒” 運用
  • 依存/FPM もワンコマンドでそろう
  • phpenv のビルド地獄から解放されて、脳内も PATH もスッキリ ✨

🐳 Dockerで“どのPHPでも即起動”──旧版テストとマルチOSを丸ごと隔離!

何を解決したい?

  • 🧹 ローカルを汚さず 7.x ~ 8.x を並列で回したい
  • 🖥 Windows/Linux 開発者と同一バイナリを共有したい
  • 🚀 CI=本番の環境差をゼロにしたい

👓 CLIだけ触れればいいっす

# PHP 8.2 CLI
docker run --rm -it -v $PWD:/app php:8.2-cli php -v

# PHP 7.4 CLI
docker run --rm -it -v $PWD:/app php:7.4-cli php -v
  • --rm で終了と同時にコンテナ破棄
  • -v $PWD:/app でホストのカレントディレクトリを /app にマウント
  • 依存ゼロ&OS問わず同じコマンドで動く

⭐️ docker-compose で FPM を常駐させる(最小構成)

# docker-compose.yml
services:
  php82:
    image: php:8.2-fpm-alpine
    ports: ["9082:9000"]
    volumes:
      - ./src:/var/www/html

  php74:
    image: php:7.4-fpm-alpine
    ports: ["9074:9000"]
    volumes:
      - ./src:/var/www/html
  • 🏃‍♂️ 複数バージョン並列で起動
  • IDE からリモート PHP interpreter にも接続しやすい
  • ./src を共有しているのでホットリロード可能

よく使う便利オプション

目的追加オプションメモ
Xdebugdocker-php-ext-install xdebug を Dockerfile にVS Code Remote 側で port=9003 を開ける
Composer キャッシュ-v ~/.composer:/tmp/composerダウンロード時間削減
タイムゾーンENV TZ=Asia/TokyoDockerfile 1 行でOK
UID/GID 揃えuser: "${UID}:${GID}"ホストと権限差異をなくす

落とし穴&Tips ⚠️

🕳 ハマりどころサッと回避
コンテナ内のファイル所有者が rootuser: "${UID}:${GID}" or docker compose exec --user $(id -u):$(id -g)
パフォーマンス低下(macOS)cached/delegated ボリューム or :consistent を外す
ログが増えすぎるlogging.driver: "json-file"max-size: "10m"

🏁 まとめ — Docker で “どのPHPでも同じ動き” を担保 🎉

  1. ワンライナーで CLI テスト → スクリプト確認
  2. compose で FPM を並列起動 → Web 動作確認
  3. 同じイメージを CI / 本番に投入 → 環境差分ゼロ

Brew で軽快に、Docker で万全に――これで PHP バージョン管理の悩みは終了!


コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です

This site uses Akismet to reduce spam. Learn how your comment data is processed.