为啥尽管在图像构建期间通过 `composer global install` 安装了“drush”,但我无法从正在运行的 PHP 脚本中找到该工具?
Posted
技术标签:
【中文标题】为啥尽管在图像构建期间通过 `composer global install` 安装了“drush”,但我无法从正在运行的 PHP 脚本中找到该工具?【英文标题】:Why despite "drush" being installed via `composer global install` during image build, I cannot find the tool from within a running PHP script?为什么尽管在图像构建期间通过 `composer global install` 安装了“drush”,但我无法从正在运行的 PHP 脚本中找到该工具? 【发布时间】:2021-08-19 14:53:50 【问题描述】:我正在 Docker 容器内开发一个 php Web 应用程序。在我的docker-compose.yml
文件中使用volumes:
,我指定了一个本地目录,以便在容器被销毁后转储并保留生成的任何文件。
volumes:
- ./docroot:/var/www/html
在我的Dockerfile
,我RUN
里面有一个安装命令行管理工具的命令:
RUN curl -sS https://getcomposer.org/installer | php && \
mv composer.phar /usr/local/bin/composer && \
ln -s /root/.composer/vendor/bin/drush /usr/local/bin/drush
RUN composer global require drush/drush:8.3.3 && \
composer global update
当容器出现时,我可以使用docker-compose exec -it <container> bash
进入容器,一切正常。 drush
在我的路径中,我可以在整个容器中全局使用它来管理应用程序。
现在是奇怪的部分。我的应用程序的一部分是我必须从容器内的 PHP 脚本运行该命令,以帮助自动管理一些构建过程。
使用 php,我运行 exec('drush dbupdate', $output, $retval);
$retval 返回退出状态 127,或者找不到命令并且 $output 为空。如果我切换 exec 以使用完整路径,我会得到退出状态 126。
如果我回到容器中,我可以正常运行该命令。请注意,所有其他 cli 命令都按预期与 exec 一起工作(ls
、whoami,
等,但 which drush
返回存在状态 1)
我错过了什么?为什么我手动可以毫无问题地使用它,但是 PHP exec()
却找不到呢? passthru()
、shell_exec()
和其他人的行为相同。
【问题讨论】:
你试过chmod +x /usr/local/bin/drush
吗?可能是某些权限或不同的用户(您以 root 身份登录,但 php 从不同的用户运行)
啊,我们到了某个地方。 whoami 显示用户 www-data,但我想我是如何从上面安装的,它可以被所有用户使用。
是的,但事实并非如此。请参阅下面的答案以了解其原因。 :)
【参考方案1】:
composer global install
不会为所有用户“全局”安装命令,而是“全局”安装,就像“为所有项目”一样。
通常,这些包安装在用户执行命令的主目录中(例如~/.composer
),如果它们在您的路径中可用是因为~/.composer/vendor/bin
被添加到会话路径中。
但是当您运行composer global require
(在构建映像时)或当您“登录”到正在运行的容器(使用exec [...] bash
)时,涉及的用户是root
。但是当您的 PHP 脚本运行时,它正在由另一个用户执行(大概是www-data
)。对于那个用户,~/.composer
不包含任何内容。
也许不要使用composer安装drush
,而是在构建映像时安装download the PHAR file directly or something like that,并将其放入/usr/local/bin
。
如果您使用 Drupal >= 8,推荐的安装 Drush 的方式不是作为“全局”依赖,而是作为“项目”依赖,以便安装适当的 drush 版本。这直接来自the docs:
建议使用 Composer 构建 Drupal 8 站点,并将 Drush 列为依赖项。该项目已经在其
composer.json
中包含了 Drush。如果您的 Composer 项目还不依赖 Drush,请运行composer require drush/drush
来添加它。完成此步骤后,您可以通过vendor/bin/drush
联系Drush
【讨论】:
很想知道为什么 ln -s ... /usr/local/bin/drush 没有按预期工作。我确实是 .phar 文件的粉丝,但是这些天 Drupal 非常依赖作曲家,我犹豫要不要走这条路。如果我查看文件的权限,它们归 root:root 777 所有。我写的内容与 mv drush.phar /usr/local/bin/drush 有何不同? 我不知道作曲家安装是否为您提供了一个可以移动的独立 phar 存档。安装 drush 的推荐方法是通过 composer,但不是全局的,而是项目本地的(因此依赖项匹配)。如果您想在所有项目中使用相同的调用路径,请为此使用“drush-ops/drush-launcher”之类的东西。以上是关于为啥尽管在图像构建期间通过 `composer global install` 安装了“drush”,但我无法从正在运行的 PHP 脚本中找到该工具?的主要内容,如果未能解决你的问题,请参考以下文章
尽管我有 Heroku 在构建期间找不到 package.json
如何使用 docker-compose 标记 docker 镜像
如何定义使用 docker-compose 构建的图像的名称