カスタムビルドしたPHPをGitHub Releaseにアップロードしてmiseで使う
mise(ミーズ)、プロジェクトディレクトリごとに別々の言語環境をセットアップするのに便利ですが PHP環境をセットアップするのは次のような不便な点があります。
mise use php@xxxコマンドをした時点でビルドする(数分かかる)mise.tomlに postinstallを設定すれば追加のPHP拡張インストールなどもできますが、同じPHPバージョンで異なる構成にする方法は不明
GitHub Release を使うことで、Configure option やPHP拡張をカスタマイズしたパッケージをアップロードし、 ネットワークが高速なら数秒でインストールできるPHPを用意できます。 プライベートリポジトリで社内向けにPHPバイナリを用意することもできそうです。
PHPをビルド・パッケージ化してGitHub ReleaseにアップロードするGitHub Actions
以下のようなファイルをGitHubリポジトリに用意します。
# .github/workflows/build-php.yml
name: Build PHP
run-name: "Build PHP ${{ inputs.php_version }}"
on:
workflow_dispatch:
inputs:
php_version:
required: true
default: "8.5.4"
permissions:
contents: write
jobs:
resolve-tag:
runs-on: ubuntu-24.04
outputs:
tag: ${{ steps.resolve.outputs.tag }}
steps:
- uses: actions/checkout@v6
- name: Resolve next build number
id: resolve
env:
GH_TOKEN: ${{ github.token }}
run: |
PREFIX="custom-php-v${{ inputs.php_version }}"
# List existing tags matching the prefix, extract build numbers
EXISTING=$(gh api repos/${{ github.repository }}/git/matching-refs/tags/"$PREFIX" --jq '.[].ref' 2>/dev/null || true)
NEXT=0
if [ -n "$EXISTING" ]; then
# Extract the highest build number from tags like refs/tags/custom-php-v8.5.4.N
MAX=$(echo "$EXISTING" | sed "s|refs/tags/${PREFIX}\.||" | sort -n | tail -1)
if [ -n "$MAX" ] && [ "$MAX" -eq "$MAX" ] 2>/dev/null; then
NEXT=$((MAX + 1))
fi
fi
TAG="${PREFIX}.${NEXT}"
echo "tag=$TAG" >> "$GITHUB_OUTPUT"
echo "Resolved tag: $TAG"
build:
needs: resolve-tag
strategy:
matrix:
os: [ubuntu-24.04, macos-15]
runs-on: ${{ matrix.os }}
env:
INSTALL_PATH: /opt/mise/data/installs/github-tenkoma-mise-php-build/custom-php-v${{ inputs.php_version }}
steps:
- name: export PATH
run: echo "PATH=$INSTALL_PATH/bin:$PATH" >> "$GITHUB_ENV"
- uses: actions/checkout@v6
# PHP をビルドするときの --prefix パスは利用するときのパスと同一にしたほうがよい
- name: Create install directories
run: |
sudo mkdir -p /opt/mise/data && sudo chown -R "$(id -u):$(id -g)" /opt/mise/data
mkdir -p $(dirname "$INSTALL_PATH")
- name: Install build dependencies (Ubuntu)
if: runner.os == 'Linux'
run: |
sudo apt-get update
sudo apt-get install -y re2c libxml2-dev libsqlite3-dev \
libcurl4-openssl-dev libonig-dev libreadline-dev libzip-dev \
libpng-dev libgd-dev libpq-dev libicu-dev libgettextpo-dev \
libtidy-dev libxslt1-dev
- name: Install build dependencies (macOS)
if: runner.os == 'macOS'
run: |
brew install autoconf re2c bison pkg-config libpng gd icu4c libpq gettext libzip libiconv bzip2 webp tidy-html5 libxslt
- name: Checkout php-build
run: git clone --depth 1 https://github.com/php-build/php-build.git
- name: Build PHP (Ubuntu)
if: runner.os == 'Linux'
env:
CFLAGS: "-std=gnu17"
CXXFLAGS: "-std=c++17"
PHP_BUILD_CONFIGURE_OPTS: "--with-gettext --with-webp"
run: |
./php-build/bin/php-build -v ${{ inputs.php_version }} "$INSTALL_PATH"
- name: Build PHP (macOS)
if: runner.os == 'macOS'
run: |
export CFLAGS="-std=gnu17"
export CXXFLAGS="-std=c++17 -stdlib=libc++ -DU_USING_ICU_NAMESPACE=1"
export PHP_BUILD_CONFIGURE_OPTS="\
--with-bz2=$(brew --prefix bzip2) \
--with-iconv=$(brew --prefix libiconv) \
--with-gettext=$(brew --prefix gettext) \
--with-libzip=$(brew --prefix libzip) \
--with-webp=$(brew --prefix webp) \
--with-zlib=$(brew --prefix zlib) \
--with-tidy=$(brew --prefix tidy-html5)"
./php-build/bin/php-build -v ${{ inputs.php_version }} "$INSTALL_PATH"
- name: Install PHP extensions via pie
run: |
pie install apcu/apcu
pie install phpredis/phpredis
- name: Package
run: |
VERSION=${{ inputs.php_version }}
OS=$(uname -s | tr '[:upper:]' '[:lower:]')
ARCH=$(uname -m)
tar -czf "custom-php-v${VERSION}-${OS}-${ARCH}.tar.gz" \
-C "$INSTALL_PATH" .
- name: Upload to Release
env:
GH_TOKEN: ${{ github.token }}
run: |
TAG="${{ needs.resolve-tag.outputs.tag }}"
# リリースが存在しなければ作成
if ! gh release view "$TAG" > /dev/null 2>&1; then
gh release create "$TAG" --title "$TAG" --notes "PHP ${{ inputs.php_version }} custom build"
fi
gh release upload "$TAG" custom-php-v*.tar.gz --clobber
Actions > Build PHP で使いたいPHPバージョンを入力して “Run workflow” を押します。

ビルド成功すると、GitHub Release にパッケージファイルが登録されています。

ここまでは mise と直接関係はありません。 PHPパッケージをアップロードするリポジトリを分けたり、タグのプレフィックスを使い分けることで同じPHPバージョンだけどビルドオプションの異なるPHPを用意できます。
ビルドしたPHPバイナリをプロジェクトで使う。
miseドキュメントにかかれているセットアップ手順は省略しますが、 ここでビルドしたPHPを利用するためには、追加の準備が必要です。
miseがツールをダウンロード&インストールするディレクトリをつくる
sudo mkdir -p /opt/mise/data && sudo chown -R "$(id -u):$(id -g)" /opt/mise/data
PHPビルド時に指定された --prefix={パス} と同じディレクトリにインストールする必要があるので同じディレクトリを作ります。
MISE_DATA_DIR環境変数を~/.zshrcに追記する
# mise
export MISE_DATA_DIR=/opt/mise/data
これで事前準備は終わりです。プロジェクトでPHPをインストールするときは以下の mise.toml を保存します。
[settings.github]
# PHPパッケージをダウンロードしたいGitHub Releaseがプライベートリポジトリの場合に必要
use_git_credentials = true
[tools]
# "github:{リポジトリ名}" = "{タグ}" 形式で
"github:tenkoma/mise-php-build" = "custom-php-v8.5"
mise trust && mise install すれば、プロジェクトディレクトリ以下にいるとき専用のPHPバージョンに切り替わります。
cd path/to/project_dir
mise trust
mise install

これでセットアップ完了です。
resolve-tag job で、バージョン番号を追加
ビルドするごとに custom-php-v8.5.4.0, custom-php-v8.5.4.1, custom-php-v8.5.4.2 とReleaseを追加します。
そうすると、 mise install で一番バージョン番号が大きいものを使いますし、 mise upgrade で更新できます。
参考ドキュメント
2026/04/01 12:20 更新
- vfox-php を使う場合openssl@1.1に依存しておりEOLを迎えているので、php-buildを使うよう変更した。
- resolve-tag jobを追加し、
mise upgradeで更新可能にした。