1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

Docker を利用して複数の PHP バージョンを切り替える

Posted at

PHP で複数バージョンを切り替える方法は調べるとたくさん出てくるのですが、今回は Docker を利用してバージョンを切り替える方法を考えてみたのでご紹介します。

なお、今回は WSL の Ubuntu 22.04.1 LTS を使用します。

Dockerfile の作成

各バージョンの設定は Dockerfile によって管理します。

まずは Dockerfile を作成するためのディレクトリを作成します。

# 今回はホームディレクトリ直下に作成します
mkdir -p ~/docker-php
cd ~/docker-php

次に Dockerfile を作成します。今回は最新、8.1、8.0 の 3 種類です。

Dockerfile.latest
FROM php:latest
Dockerfile.8_1
FROM php:8.1
Dockerfile.8_0
FROM php:8.0

エイリアスの作成

今回は ~/.bash_aliases に以下を追記します。
環境によっては ~/.bashrc~/.bash_profile となることもあります。

# Docker
# ファイル書き込みの際に root 権限にならないよう、ユーザを指定する
alias dkrun="docker run --rm -it -u $(id -u):$(id -g)"
alias dkrunroot="docker run --rm -it"

# PHP (docker)
DOCKER_PHP_DIR=~/docker-php
DOCKER_PHP_REPO=local/php
docker_php() {
  version=$1
  docker_tag=local/php:${version}
  snake_case_version=$(echo "${version}" | tr '.' '_')

  # イメージがない場合や、アップデートする場合はビルドする
  if [ -z "$(docker images --quiet --filter=reference=${DOCKER_PHP_REPO}:"${version}")" ] || [ "$2" = "--update" ]; then
    docker build --no-cache --pull --file ${DOCKER_PHP_DIR}/Dockerfile."${snake_case_version}" --tag "${docker_tag}" .
  fi

  # アップデートの場合はその後コマンドを実行しない
  if [ "$2" = "--update" ]; then
    return
  fi

  # コマンドを実行する
  if [ "$2" = "bash" ]; then
    dkrunroot -v "$(pwd)":/app -w /app "${docker_tag}" "${@:2}"
  elif [ -z "$2" ]; then
    dkrun -v "$(pwd)":/app -w /app "${docker_tag}"
  else
    dkrun -v "$(pwd)":/app -w /app "${docker_tag}" php "${@:2}"
  fi
}
# 指定されたディレクトリにある Dockerfile の一覧を読み取り、エイリアスを設定する
# すでにインストールされている PHP と区別するために dphp と付けています。
for snake_case_version in "${DOCKER_PHP_DIR}"/Dockerfile.*; do
  snake_case_version=$(echo "$snake_case_version" | rev | cut -d'/' -f1 | rev | sed 's/^Dockerfile\.//')
  if [ "$snake_case_version" == "latest" ]; then
    alias dphp='docker_php latest'
  else
    alias "dphp$(echo "$snake_case_version" | tr -d '_')=docker_php $(echo "$snake_case_version" | tr '_' '.')"
  fi
done

追記が終わったら、シェルを再起動するか source ~/.bash_aliases でエイリアスを読み込みます。

実行してみる

最新の PHP が実行できるか試してみましょう。

dphp --version

ビルドが始まり、以下のように PHP のバージョンが表示されれば OK です。

PHP 8.2.3 (cli) (built: Feb 14 2023 20:22:21) (NTS)
Copyright (c) The PHP Group
Zend Engine v4.2.3, Copyright (c) Zend Technologies

同様に dphp81 --versiondphp80 --version も試してみましょう。

拡張モジュールの追加

拡張モジュールを追加するには Dockerfile を編集します。
今回は zip モジュールを追加してみましょう。

私が試した時点では zip モジュールは標準で入っていないので、以下のコマンドを実行しても何も出力されないはずです。

dphp -m | grep zip

引数に bash を渡すことで、コンテナにログインし、必要なコマンドをリハーサルします。

dphp bash

コマンドが決まったら Dockerfile へ追記します。

Dockerfile.latest
FROM php:latest

RUN apt update && \
    apt install -y libzip-dev && \
    docker-php-ext-install zip

イメージをアップデートします。

dphp --update

もう一度モジュールの存在を確認します。

dphp -m | grep zip

zip と出てくれば zip モジュールがインストールされています!

アンインストール

PHP の特定バージョンをアンインストールする場合、Docker イメージを削除するだけです。

例えば 8.1 をアンインストールする場合は以下のコマンドを実行します。

docker rmi $(docker images --quiet --filter=reference=local/php:8.1)

キャッシュなども含めて完全に削除する場合は docker system prune を実行してください。

1
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?