I’ve got a docker image running 8.0 and want to upgrade to 8.1. I have updated the image to run with PHP 8.1 and want to update the dependencies in it.
The new image derives from php:8.1.1-fpm-alpine3.15
I’ve updated the composer.json
and changed require.php
to ^8.1
but ran into the following message when running composer upgrade
:
Root composer.json requires php ^8.1 but your php version (8.0.14) does not satisfy that requirement.
What I find dazzling is that the composer incorrectly identifies PHP version. I used two commands to determine that:
which php # returns only /usr/local/bin/php
/usr/local/bin/php -v # returns PHP 8.1.1 (cli) (built: Dec 18 2021 01:38:53) (NTS)
So far I’ve tried:
- Checking
php -v
- Clearing composer cache
- Rebuilding image
Composer version 2.1.12 2021-11-09 16:02:04
composer check-platform-reqs | grep php
# returns:
# ...
# php 8.0.14 project/name requires php (^8.1) failed
All of the commands above (excluding docker commands) are being ran in the container
Dockerfile:
FROM php:8.1.1-fpm-alpine3.15
ENV TZ=Europe/London
# Install php lib deps
RUN apk update && apk upgrade
RUN apk add --update libzip-dev
zip
unzip
libpng-dev
nginx
supervisor
git
curl
shadow
composer
yarn && rm -rf /var/cache/apk/*
RUN usermod -u 1000 www-data
RUN usermod -d /var/www www-data
RUN mkdir -p /run/nginx && chown www-data:www-data /run/nginx
ENV SUPERCRONIC_URL=https://github.com/aptible/supercronic/releases/download/v0.1.9/supercronic-linux-amd64
SUPERCRONIC=supercronic-linux-amd64
SUPERCRONIC_SHA1SUM=5ddf8ea26b56d4a7ff6faecdd8966610d5cb9d85
RUN curl -fsSLO "$SUPERCRONIC_URL"
&& echo "${SUPERCRONIC_SHA1SUM} ${SUPERCRONIC}" | sha1sum -c -
&& chmod +x "$SUPERCRONIC"
&& mv "$SUPERCRONIC" "/usr/local/bin/${SUPERCRONIC}"
&& ln -s "/usr/local/bin/${SUPERCRONIC}" /usr/local/bin/supercronic
# Install and enable php extensions
RUN docker-php-ext-install sockets mysqli pdo_mysql zip gd bcmath > /dev/null
ARG ENV="development"
# Xdebug install
RUN if [ $ENV = "development" ] ; then
apk add --no-cache $PHPIZE_DEPS;
pecl install xdebug > /dev/null;
docker-php-ext-enable xdebug;
echo "error_reporting = E_ALL" >> /usr/local/etc/php/conf.d/docker-php-ext-xdebug.ini;
echo "display_startup_errors = On" >> /usr/local/etc/php/conf.d/docker-php-ext-xdebug.ini;
echo "display_errors = On" >> /usr/local/etc/php/conf.d/docker-php-ext-xdebug.ini;
echo "xdebug.remote_enable=1" >> /usr/local/etc/php/conf.d/docker-php-ext-xdebug.ini;
fi ;
# Setup working directory
RUN chown -R www-data:www-data /var/www
WORKDIR /var/www
USER www-data
# Install dependencies
#RUN if [ $ENV = "development" ] ; then
## composer install -n;
# else
## composer install -n --no-dev;
# fi ;
# Generate doctrine proxies
2
Answers
Huh. This surprised me a bit.
composer is correctly reporting the PHP version it’s using. The problem is that it’s not using the "correct" PHP interpreter.
The issue arises because of how you are installing composer.
Apparently by doing
apk add composer
another version of PHP gets installed (you can find it on/usr/bin/php8
, this is the one on version 8.0.14).Instead of letting
apk
install composer for you, you can do it manually. There is nothing much to install it in any case, no need to go through the package manager. Particularly since PHP has not been installed via the package manager on your base image.I’ve just removed the line containing
composer
from theapk add --update
command, and added this somewhere below:You could also simply download the latest composer PHAR file from here, and add it to the image, depending on how you want to go.
Now there is a single PHP version, and composer will run correctly on PHP 8.1.1.
This also struck me by a surprise and especially in development or build images that ship with their own PHP versions (e.g. official PHP docker images in the Alpine variant) this makes not much sense.
Not limited but tested on Alpine thought, here an install variant for a specific Composer version with checksum validation (the Composer Download page has all versions and checksums):
Output (exemplary):
self-update
command. As this version is installed without the installer, they are not set-up.It spares the installer (hence no pubkeys) and pins the version (for stable building you would need to pin the installer version or fetch the checksum of the installer via https, Composer outlines it here in their docs: How do I install Composer programmatically?; this is additional info as the previous answer does not mention this explicitly).
I’ve put the composer diagnose command into the build section so that at least it shows a good overview (from composers perspective) and may give as well some hints on how to improve the image depending on the base image and configuration. E.g. install additional command-line utilities, in a build image you perhaps want to have git(1) as well with composer, not only unzip(1).