skip to Main Content

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


  1. 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 the apk add --update command, and added this somewhere below:

     RUN php -r "copy('https://getcomposer.org/installer', 'composer-setup.php');" && 
         php -r "if (hash_file('sha384', 'composer-setup.php') === '906a84df04cea2aa72f40b5f787e49f22d4c2f19492ac310e8cba5b96ac8b64115ac402c8cd292b8a03482574915d1a8') { echo 'Installer verified'; } else { echo 'Installer corrupt'; unlink('composer-setup.php'); } echo PHP_EOL;" && 
         php composer-setup.php && 
         php -r "unlink('composer-setup.php');" && 
         mv composer.phar /usr/local/bin/composer;
    

    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.

    Login or Signup to reply.
  2. 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):

    FROM php:8.1-alpine
    
    ARG COMPOSER_BIN=/usr/bin/composer
    ARG COMPOSER_VERSION=2.2.12
    ARG COMPOSER_SHA256SUM=1ce90687eb3f89a99c059d45dd419d08430ed249468544b932b1dad7fb22dda0
    
    RUN set -ex ;
      wget -O "$COMPOSER_BIN" "https://getcomposer.org/download/$COMPOSER_VERSION/composer.phar" ;
      printf "%s  %sn" "$COMPOSER_SHA256SUM" "$COMPOSER_BIN" | sha256sum -c - ;
      chmod +x -- "$COMPOSER_BIN" ;
      composer --version ;
      composer diagnose || printf 'composer diagnose exited: %dn' $? ;
      :
    

    Output (exemplary):

    Sending build context to Docker daemon  2.048kB # (1)
    Step 1/5 : FROM php:8.1-alpine
     ---> 77506786976c
    Step 2/5 : ARG COMPOSER_BIN=/usr/bin/composer
     ---> Running in 71db8206ae0b
    Removing intermediate container 71db8206ae0b
     ---> 77432ca0a59a
    Step 3/5 : ARG COMPOSER_VERSION=2.2.12
     ---> Running in 5d0e6f5bee3d
    Removing intermediate container 5d0e6f5bee3d
     ---> 273a0d9d2936
    Step 4/5 : ARG COMPOSER_SHA256SUM=1ce90687eb3f89a99c059d45dd419d08430ed249468544b932b1dad7fb22dda0
     ---> Running in 504ad490732a
    Removing intermediate container 504ad490732a
     ---> e56499db14c7
    Step 5/5 : RUN set -ex ;  wget -O "$COMPOSER_BIN" "https://getcomposer.org/download/$COMPOSER_VERSION/composer.phar" ;  printf "%s  %sn" "$COMPOSER_SHA256SUM" "$COMPOSER_BIN" | sha256sum -c - ;  chmod +x -- "$COMPOSER_BIN" ;  composer --version ;  composer diagnose || printf 'composer diagnose exited: %dn' $? ;  :
     ---> Running in 10c303e61d27
    + wget -O /usr/bin/composer https://getcomposer.org/download/2.2.12/composer.phar
    Connecting to getcomposer.org (54.36.53.46:443)
    saving to '/usr/bin/composer'
    composer             100% |********************************| 2312k  0:00:00 ETA
    '/usr/bin/composer' saved
    + printf '%s  %sn' 1ce90687eb3f89a99c059d45dd419d08430ed249468544b932b1dad7fb22dda0 /usr/bin/composer
    + sha256sum -c -
    /usr/bin/composer: OK
    + chmod +x -- /usr/bin/composer
    + composer --version
    Composer version 2.2.12 2022-04-13 16:42:25
    + composer diagnose
    Checking platform settings: OK
    Checking git settings: OK
    Checking http connectivity to packagist: OK
    Checking https connectivity to packagist: OK
    Checking github.com rate limit: OK
    Checking disk free space: OK
    Checking pubkeys: FAIL # (2)
    Missing pubkey for tags verification
    Missing pubkey for dev verification
    Run composer self-update --update-keys to set them up
    Checking composer version: You are not running the latest stable version, run `composer self-update` to update (2.2.12 => 2.3.5)
    Composer version: 2.2.12
    PHP version: 8.1.4
    PHP binary path: /usr/local/bin/php
    OpenSSL version: OpenSSL 1.1.1n  15 Mar 2022
    cURL version: 7.80.0 libz 1.2.12 ssl OpenSSL/1.1.1n
    zip: extension not loaded, unzip present, 7-Zip not available
    + printf 'composer diagnose exited: %dn' 2
    + :
    composer diagnose exited: 2
    Removing intermediate container 10c303e61d27
    ...
    
    1. Dockerfile as TAR, four 512 byte blocks (one file-entry-block, one file content-block, two NUL byte blocks as end-of-archive indicator; compare)
    2. Composer public keys are in use with the 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).

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search