【问题标题】:PHP Docker install pecl V8JS (Debian Buster)PHP Docker 安装 pecl V8JS (Debian Buster)
【发布时间】:2020-07-04 10:39:23
【问题描述】:

我尝试用这个 Dockerfile 安装 V8JS

FROM php:7.3-cli-buster

RUN apt-get update -y --fix-missing && apt-get upgrade -y;

# Install v8js
RUN apt-get install -y libv8-dev
RUN pecl install v8js
RUN docker-php-ext-enable v8js

但我遇到了配置错误:

正在检查默认路径中的 V8 文件...未找到

配置:错误:请重新安装 v8 发行版错误: `/tmp/pear/temp/v8js/configure --with-php-config=/usr/local/bin/php-config --with-v8js' 失败 命令'/bin/sh -c pecl install v8js' 返回非零代码:1

完整的 cli 输出:

Sending build context to Docker daemon   35.6MB
Step 1/5 : FROM php:7.3-cli-buster
 ---> c7ff0bf4f6fb
Step 2/5 : RUN apt-get update -y --fix-missing && apt-get upgrade -y;
 ---> Using cache
 ---> e151d6e061d2
Step 3/5 : RUN apt-get install -y libv8-dev
 ---> Using cache
 ---> fe35f48dd8cf
Step 4/5 : RUN pecl install v8js
 ---> Running in d9f4ba184d81
downloading v8js-2.1.1.tgz ...
Starting to download v8js-2.1.1.tgz (101,888 bytes)
.......................done: 101,888 bytes
28 source files, building
running: phpize
Configuring for:
PHP Api Version:         20180731
Zend Module Api No:      20180731
Zend Extension Api No:   320180731
Please provide the installation prefix of libv8 [autodetect] : building in /tmp/pear/temp/pear-build-defaultuserEVh9Nq/v8js-2.1.1
running: /tmp/pear/temp/v8js/configure --with-php-config=/usr/local/bin/php-config --with-v8js
checking for grep that handles long lines and -e... /bin/grep
checking for egrep... /bin/grep -E
checking for a sed that does not truncate output... /bin/sed
checking for cc... cc
checking whether the C compiler works... yes
checking for C compiler default output file name... a.out
checking for suffix of executables...
checking whether we are cross compiling... no
checking for suffix of object files... o
checking whether we are using the GNU C compiler... yes
checking whether cc accepts -g... yes
checking for cc option to accept ISO C89... none needed
checking how to run the C preprocessor... cc -E
checking for icc... no
checking for suncc... no
checking whether cc understands -c and -o together... yes
checking for system library directory... lib
checking if compiler supports -R... no
checking if compiler supports -Wl,-rpath,... yes
checking build system type... x86_64-pc-linux-gnu
checking host system type... x86_64-pc-linux-gnu
checking target system type... x86_64-pc-linux-gnu
checking for PHP prefix... /usr/local
checking for PHP includes... -I/usr/local/include/php -I/usr/local/include/php/main -I/usr/local/include/php/TSRM -I/usr/local/include/php/Zend -I/usr/local/include/php/ext -I/usr/local/include/php/ext/date/lib
checking for PHP extension directory... /usr/local/lib/php/extensions/no-debug-non-zts-20180731
checking for PHP installed headers prefix... /usr/local/include/php
checking if debug is enabled... no
checking if zts is enabled... no
checking for re2c... re2c
checking for re2c version... 1.1.1 (ok)
checking for gawk... no
checking for nawk... nawk
checking if nawk is broken... no
checking for V8 Javascript Engine... yes, shared
checking for V8 files in default path... not found
configure: error: Please reinstall the v8 distribution
ERROR: `/tmp/pear/temp/v8js/configure --with-php-config=/usr/local/bin/php-config --with-v8js' failed
The command '/bin/sh -c pecl install v8js' returned a non-zero code: 1

如何解决配置错误(我猜是因为缺少 V8 文件的路径)并在 PHP Docker FROM Debian Buster 上安装 V8JS?

编辑

来自@saulotoledo 答案的Dockerfile 有效:)

构建映像大约需要 60-90 分钟,映像大小为 5.47GB,而基础映像 (FROM) 7.3-cli-buster 367MB​​

要使用 V8JS 构建 Dockerfile php,请从 @saulotoledo 答案中复制代码并将其粘贴到名为 Dockerfile 的文件中

然后在同一目录下运行这个命令:

docker build --tag "test-php-js" .

然后以这种方式运行容器:

docker run -it --rm --entrypoint="" --name="php-v8js" test-php-js /bin/sh

你应该登录到 php-cli 的终端,输入:

php -m

您应该会看到已启用的扩展程序列表,包括 v8js

类型:

php --ri v8js

查看一些细节,例如:

V8 Javascript Engine => enabled
V8 Engine Compiled Version => 7.4.288.21
V8 Engine Linked Version => 7.4.288.21
Version => 2.1.1

现在是你们一直在等待的樱桃部分 - 输入:

php -r "(new V8Js())->executeString(\"print('Hello' + ' from JS ' + 'World!')\", 'basic.js');";

查看支持 V8JS 的 php 运行 js 代码:D

Hello from JS World!

请注意,对于 php -r 命令,我需要在每个 JS 双引号 " 前面加上额外的反斜杠 \。但这只是由于在 cli 模式下从 php 运行 JS 作为 oneliner。

通常你不需要那个 See an official PHP documentation example

有谁知道是否可以安装和启用 V8JS 扩展而不从其源代码构建它,而是像我一开始尝试的那样使用 Debian Buster 包和 PECL?

【问题讨论】:

  • 您是否已经看到github.com/phpv8/v8js/issues/206 导致此处的文档:github.com/phpv8/v8js/blob/php7/README.Linux.md?这对你有帮助吗?
  • @ChristophKluge 我尝试了提供的示例代码here,但我收到关于fetch v8 行的错误“找不到命令”。我之前添加了RUN apt-get install -y fetch,但存储库中没有这样的包。我不知道fetch 是什么。你知道那个 fetch 是什么,我从哪里得到它?
  • fetchdepot_tools.git repo 的一部分,它被加载到你的PATH 中。您是否运行git clone https://chromium.googlesource.com/chromium/tools/depot_tools.git 后跟export PATH=$(pwd)/depot_tools:"$PATH"?这应该导出fetchgclient。见这里:chromium.googlesource.com/chromium/tools/depot_tools.git#tools
  • 我正在为您准备一个示例 Dockerfile。它仍在编译。我现在必须离开,但我一回来会给你一个工作副本/粘贴示例的答案。
  • @ChristophKluge 谢谢,我会跟踪该票的回复。我还发现 another phpv8/v8js/issue 似乎已解决,但尚未检查是否有帮助。

标签: php docker configuration debian v8js


【解决方案1】:

感谢 saulotoledo,我创建了 950MB 和 398MB 基本图像的示例图像 (php:7.3-cli-buster)

它也适用于 PHP FPM,只需更改 FROM php:7.3-cli-busterFROM php:7.3-fpm-buster 如果你想要 FPM 版本。

Dockerfile

FROM php:7.3-cli-buster
ENV V8_VERSION=7.4.288.21
# php:7.3-cli-buster 398MB

RUN apt-get update -y --fix-missing && apt-get upgrade -y;

# Install required CLI tools
RUN apt-get install -y --no-install-recommends \
    libtinfo5 libtinfo-dev \
    build-essential \
    curl \
    git \
    libglib2.0-dev \
    libxml2 \
    python \
    patchelf

# Install V8, PHP's V8Js
RUN cd /tmp \
    \
    && git clone https://chromium.googlesource.com/chromium/tools/depot_tools.git --progress --verbose \
    && export PATH="$PATH:/tmp/depot_tools" \
    \
    && fetch v8 \
    && cd v8 \
    && git checkout $V8_VERSION \
    && gclient sync \
    && tools/dev/v8gen.py -vv x64.release -- is_component_build=true use_custom_libcxx=false \
    \
    && cd /tmp/v8 \
    && ninja -C out.gn/x64.release/ \
    && mkdir -p /opt/v8/lib && mkdir -p /opt/v8/include \
    && cp out.gn/x64.release/lib*.so out.gn/x64.release/*_blob.bin out.gn/x64.release/icudtl.dat /opt/v8/lib/ \
    && cp -R include/* /opt/v8/include/ \
    && for A in /opt/v8/lib/*.so; do patchelf --set-rpath '$ORIGIN' $A;done \
    \
    && cd /tmp \
    && git clone https://github.com/phpv8/v8js.git \
    && cd v8js \
    && phpize \
    && ./configure --with-v8js=/opt/v8 LDFLAGS="-lstdc++" \
    && make \
    && make test \
    && make install \
    \
    && docker-php-ext-enable v8js \
    \
    && rm -rf "/tmp/v8" \
    && rm -rf "/tmp/depot_tools"

# Image size after removing source files 950MB

【讨论】:

    【解决方案2】:

    编辑: 那应该可以解决您的问题(请注意,我是手动编译的):

    FROM php:7.3-cli-buster
    ENV V8_VERSION=7.4.288.21
    
    RUN apt-get update -y --fix-missing && apt-get upgrade -y;
    
    # Install v8js (see https://github.com/phpv8/v8js/blob/php7/README.Linux.md)
    RUN apt-get install -y --no-install-recommends \
        libtinfo5 libtinfo-dev \
        build-essential \
        curl \
        git \
        libglib2.0-dev \
        libxml2 \
        python \
        patchelf \
        && cd /tmp \
        \
        && git clone https://chromium.googlesource.com/chromium/tools/depot_tools.git --progress --verbose \
        && export PATH="$PATH:/tmp/depot_tools" \
        \
        && fetch v8 \
        && cd v8 \
        && git checkout $V8_VERSION \
        && gclient sync \
        \
        && tools/dev/v8gen.py -vv x64.release -- is_component_build=true use_custom_libcxx=false
    
    RUN export PATH="$PATH:/tmp/depot_tools" \
        && cd /tmp/v8 \
        && ninja -C out.gn/x64.release/ \
        && mkdir -p /opt/v8/lib && mkdir -p /opt/v8/include \
        && cp out.gn/x64.release/lib*.so out.gn/x64.release/*_blob.bin out.gn/x64.release/icudtl.dat /opt/v8/lib/ \
        && cp -R include/* /opt/v8/include/ \
        && apt-get install patchelf \
        && for A in /opt/v8/lib/*.so; do patchelf --set-rpath '$ORIGIN' $A;done
    
    # Install php-v8js
    RUN cd /tmp \
        && git clone https://github.com/phpv8/v8js.git \
        && cd v8js \
        && phpize \
        && ./configure --with-v8js=/opt/v8 LDFLAGS="-lstdc++" \
        && make \
        && make test \
        && make install
    
    RUN docker-php-ext-enable v8js
    

    旧答案:

    我相信您需要手动编译 V8。我还不确定为什么 libv8-dev 还不够。由于这不起作用,您需要编译它,因为it is a requirement

    也就是说,this link 可能会有所帮助。但是官方的编译说明是提供here。经过几次测试后,我注意到您需要在您的apt-get install 中添加libtinfo5(可能还有libtinfo-dev,以确保安全,但您可以尝试不使用它),否则说明中的忍者构建将失败。

    在您的 Dockerfile 中使用该编译指令后,V8 将正确编译。之后,您在安装 pecl 时仍然会遇到一些问题。不幸的是,我现在不得不停止调查这个问题,编译需要一些时间。但是,以下链接可能会帮助您解决问题:

    • This one 如果您仍然无法使用 ninja 进行编译
    • This one 提供了另一个用于编译 V8 的 Dockerfile,但基础镜像不同,需要一些调整。

    我希望它有所帮助。如果您设法拥有一个工作的 Dockerfile,请稍后与我们分享。如果我以后有时间调查它并且我有一些进展,我会编辑我的答案。

    【讨论】:

    • @Jimmix 请检查这是否回答了您的问题。 :)
    • && cp out.gn/x64.release/lib*.so out.gn/x64.release/*_blob.bin out.gn/x64.release/icudtl.dat /opt/v8/lib/ 失败并出现错误:“cp: target '/opt/v8/lib/' is not a directory”。奇怪,因为您已经在它前面放了&& mkdir -p /opt/v8/{lib,include} \ 并且它没有失败,所以 IMO 应该可以使用 cp .. 但它不是。你知道可能是什么原因吗?顺便说一句,构建 Dockerfile 大约需要 1.5 小时,直到出现错误:)
    • 我刚刚复制了错误。在这里复制最终的 Dockerfile 时,我可能忘记了一些东西。让我试着找出我错过的东西。是的,编译 oO' 需要很长时间,这不是很好的部分......我正在阅读的链接之一中的一个人建议预编译它并将其复制到您的容器中。我也在测试容器内部的命令:docker run -it base_container_id /bin/bash(可能同时这些信息对你有用)
    • @Jimmix 呃... docker 正在创建一个名为 {lib,include} 的文件夹。我们只需要更新脚本中的 mkdir 行。我现在会更新答案。很抱歉这个错误。
    • 谢谢!它有效,我只需要删除 sudo 并添加 docker ext enable (我编辑了你的 Dockerfile)。请在编辑后查看我的问题以查看结果。