[英]Why despite "drush" being installed via `composer global install` during image build, I cannot find the tool from within a running PHP script?
I am developing a PHP web application inside of a Docker container.我正在 Docker 容器内开发 PHP web 应用程序。 Using
volumes:
inside of my docker-compose.yml
file, I have specified a local directory so that any files generated are dumped and persist after the container is destroyed.使用
volumes:
在我的docker-compose.yml
文件中,我指定了一个本地目录,以便在容器被销毁后转储并保留生成的任何文件。
volumes:
- ./docroot:/var/www/html
Inside my Dockerfile
, I RUN
a command that installs a command line management tool:在我的
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
When the container comes up, I can use docker-compose exec -it <container> bash
to get inside the container, and everything works fine.当容器出现时,我可以使用
docker-compose exec -it <container> bash
进入容器,一切正常。 drush
is in my path, and I can use it globally throughout the container to manage the app. drush
在我的路径中,我可以在整个容器中全局使用它来管理应用程序。
Now here is the strange part.现在这是奇怪的部分。 Part of my application is that I have to run that command from a PHP script inside the container to help automatically manage some of the build process.
我的应用程序的一部分是我必须从容器内的 PHP 脚本运行该命令,以帮助自动管理一些构建过程。
Using php, I run exec('drush dbupdate', $output, $retval);
使用 php,我运行
exec('drush dbupdate', $output, $retval);
$retval returns a exit status of 127, or command not found and $output is empty. $retval 返回退出状态 127,或未找到命令且 $output 为空。 If I switch up the exec to use the full path I get an exit status 126.
如果我切换 exec 以使用完整路径,我会得到退出状态 126。
If I go back into the container, I can run that command just fine.如果我 go 回到容器中,我可以正常运行该命令。 Note all other cli commands work as expected with exec (
ls
, whoami,
etc but which drush
returns exist status 1)请注意,所有其他 cli 命令都按预期与 exec 一起工作(
ls
、 whoami,
等,但which drush
返回存在状态 1)
What am I missing?我错过了什么? Why can I use it with no problems manually, but PHP
exec()
can't find it?为什么我可以手动使用没有问题,但是 PHP
exec()
却找不到? passthru()
, shell_exec()
, and others have the same behavior. passthru()
、 shell_exec()
和其他具有相同的行为。
composer global install
will not install the command "globally" for all users, but "globally" as in "for all projects". composer global install
不会为所有用户安装“全局”命令,而是“全局”安装,就像“所有项目”一样。
Generally, these packages are installed in the home directory for the user executing the command (eg ~/.composer
), and if they are available in your path is because ~/.composer/vendor/bin
is added to the session path.通常,这些包安装在用户执行命令的主目录中(例如
~/.composer
),如果它们在您的路径中可用,是因为~/.composer/vendor/bin
已添加到 session 路径中。
But when you run composer global require
(while building the image) or when you "log in" to the running container (using exec [...] bash
) the user involved is root
.但是,当您运行
composer global require
(在构建映像时)或当您“登录”到正在运行的容器时(使用exec [...] bash
),所涉及的用户是root
。 But when your PHP script runs, it's being executed by another user (presumably www-data
).但是当您的 PHP 脚本运行时,它正在由另一个用户(大概是
www-data
)执行。 And for that user, ~/.composer
does not contain anything.对于该用户,
~/.composer
不包含任何内容。
Maybe do not install drush
using composer, but rather download the PHAR file directly or something like that while you are building the image, and put it in /usr/local/bin
.也许不要使用 composer 安装
drush
,而是在构建映像时直接下载 PHAR 文件或类似的文件,并将其放入/usr/local/bin
。
If you are using Drupal >= 8, the recommended way of installing Drush is not as a "global" dependency, but as "project" dependency, so that the appropriate drush version is installed.如果您使用的是 Drupal >= 8,则推荐的安装 Drush 的方式不是作为“全局”依赖,而是作为“项目”依赖,以便安装适当的 drush 版本。 This comes straight from the docs :
这直接来自文档:
It is recommended that Drupal 8 sites be built using Composer, with Drush listed as a dependency.
建议使用 Composer 构建 Drupal 8 个站点,并将 Drush 列为依赖项。 That project already includes Drush in its
composer.json
.该项目已经在其
composer.json
中包含了 Drush。 If your Composer project doesn't yet depend on Drush, runcomposer require drush/drush
to add it.如果您的 Composer 项目还不依赖 Drush,请运行
composer require drush/drush
来添加它。 After this step, you may call Drush viavendor/bin/drush
完成此步骤后,您可以通过
vendor/bin/drush
调用 Drush
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.