使用 Alpine 的 apk 命令安装 composer 时使用了错误的 PHP 版本

Wrong PHP version used when installing composer with Alpine's apk command

我有一个 docker 映像 运行ning 8.0,想升级到 8.1。我已经使用 PHP 8.1 将图像更新为 运行 并希望更新其中的依赖项。

新图像来自php:8.1.1-fpm-alpine3.15

我已经更新了 composer.json 并将 require.php 更改为 ^8.1 但是 运行 在 运行ning composer upgrade 时变为以下消息:

Root composer.json requires php ^8.1 but your php version (8.0.14) does not satisfy that requirement.

令我眼花缭乱的是作曲家错误地识别了 PHP 版本。我使用了两个命令来确定:

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)

到目前为止我已经尝试过:

Composer 版本 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  

以上所有命令(不包括 docker 命令)都在 运行 容器中

Docker 文件:

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

嗯。这让我有点吃惊。

composer 正确报告了它正在使用的 PHP 版本。问题是它没有使用“正确的”PHP 解释器。

出现此问题是因为您安装 composer 的方式。

显然通过 apk add composer 安装了另一个版本的 PHP(您可以在 /usr/bin/php8 上找到它,这是版本 8.0.14 上的版本)。

您可以手动完成,而不是让 apk 为您安装 composer。在任何情况下都没有什么可安装的,不需要通过包管理器。特别是因为 PHP 尚未通过包管理器安装在您的基础映像上。

我刚刚从 apk add --update 命令中删除了包含 composer 的行,并将其添加到下面的某处:

 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;

您也可以从 here 下载最新的 composer PHAR 文件,然后将其添加到图像中,具体取决于您想要的方式。

现在只有一个 PHP 版本,作曲家将 运行 在 PHP 8.1.1 上正确 运行。

这也让我感到惊讶,尤其是在开发或构建带有自己的 PHP 版本(例如 official PHP docker images in the Alpine variant)的图像时,这没有多大意义。

不受限制,但在 Alpine thought 上进行了测试,这里是具有校验和验证的特定 Composer 版本的安装变体(Composer Download page 具有所有版本和校验和):

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  %s\n" "$COMPOSER_SHA256SUM" "$COMPOSER_BIN" | sha256sum -c - ;\
  chmod +x -- "$COMPOSER_BIN" ;\
  composer --version ;\
  composer diagnose || printf 'composer diagnose exited: %d\n' $? ;\
  :

输出(示例):

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  %s\n" "$COMPOSER_SHA256SUM" "$COMPOSER_BIN" | sha256sum -c - ;  chmod +x -- "$COMPOSER_BIN" ;  composer --version ;  composer diagnose || printf 'composer diagnose exited: %d\n' $? ;  :
 ---> 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  %s\n' 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: %d\n' 2
+ :
composer diagnose exited: 2
Removing intermediate container 10c303e61d27
...
  1. Dockerfile作为TAR,四个512字节块(一个file-entry-block,一个文件content-block,两个NUL字节块作为end-of-archive指标;compare )
  2. Composer public keysself-update 命令一起使用。由于此版本是在没有安装程序的情况下安装的,因此它们不是 set-up.

它会保留安装程序(因此没有公钥)并固定版本(为了稳定构建,您需要固定安装程序版本通过 https 获取安装程序的校验和, Composer 在他们的文档中概述了它:How do I install Composer programmatically?; this is additional info as 没有明确提到这一点)。

我已经将 composer diagnose 命令放入构建部分,这样至少它显示了一个很好的概述(从作曲家的角度来看)并且可能还会给出一些关于如何根据基本图像和改进图像的提示配置。例如。安装额外的 command-line 实用程序,在构建映像中你可能希望 git(1) 以及 composer,而不仅仅是 unzip(1).