8wDlpd.png
8wDFp9.png
8wDEOx.png
8wDMfH.png
8wDKte.png

Ubuntu 上的 Docker 化 Chromium

seans 2月前

119 0

我希望在 Dockerised Ubuntu 22 中运行不使用 Snap Manger 的 Chromium。Docker 20.10.25Chromium 128.0.6551.0 运行此命令时:chrome --headless=new --dump-dom --ignore-ssl-errors --no-

我希望在 Dockerised Ubuntu 22 中运行不带 Snap Manger 的 Chromium。

  • Docker 20.10.25
  • 铬 128.0.6551.0

运行此命令时:

chrome --headless=new --dump-dom --ignore-ssl-errors --no-sandbox https://domains.google.com/checkip

它响应了一个错误,太长,无法在这里发布,其要点如下:

[8:24:0621/192304.523348:ERROR:bus.cc(407)] Failed to connect to the bus: Failed to connect to socket /run/dbus/system_bus_socket: No such file or directory

[8:24:0621/192304.544534:ERROR:bus.cc(407)] Failed to connect to the bus: Could not parse server address: Unknown address type (examples of valid types are "tcp" and on UNIX "unix")

DevTools listening on ws://127.0.0.1:9222/devtools/browser/fcf3d3a5-9cea-4fa9-85f9-cf18b2a8323c


[8:34:0621/192304.915840:ERROR:cert_verify_proc_builtin.cc(1063)] CertVerifyProcBuiltin for www.google.com failed:

Docker 配置是

FROM ubuntu:22.04

EXPOSE 9222

ENV CHROMIUM_DOWNLOAD_HOST=https://storage.googleapis.com
ENV LASTCHANGE_URL="https://www.googleapis.com/download/storage/v1/b/chromium-browser-snapshots/o/Linux_x64%2FLAST_CHANGE?alt=media"
ENV VERSION='eval curl $LASTCHANGE_URL'
ARG USERNAME=chromium
ARG USER_UID=1000
ARG USER_GID=$USER_UID
ENV HOME=/data

RUN apt-get update && DEBIAN_FRONTEND="noninteractive" apt-get -y install apt-transport-https \
    ca-certificates curl fonts-liberation gconf-service gnupg \
    inotify-tools jq libappindicator1 libappindicator3-1 libasound2 libatk1.0-0 \
    libatk-bridge2.0-0 libatspi2.0-0 libc6 libcairo2 libcups2 libdbus-1-3 \
    libexpat1 libfontconfig1 libgbm1 libgcc1 libgconf-2-4 libgdk-pixbuf2.0-0 \
    libglib2.0-0 libgtk-3-0 libjq1 libnspr4 libnss3 libonig5 libnss3-tools \
    libpango-1.0-0 libpangocairo-1.0-0 libstdc++6 libx11-6 libx11-xcb1 libxcb1 \
    libxcomposite1 libxcursor1 libxdamage1 libxext6 libxfixes3 libxi6 libxkbcommon0 \
    libxrandr2 libxrender1 libxss1 libxtst6 lsb-release unzip xdg-utils xvfb strace vim \
    && rm -rf /var/lib/apt/lists/* /var/cache/apt/*

RUN curl -o chrome-linux.zip "$CHROMIUM_DOWNLOAD_HOST/chromium-browser-snapshots/Linux_x64/$($VERSION)/chrome-linux.zip" \
    && unzip chrome-linux.zip -d /usr/local/bin \
    && rm chrome-linux.zip

RUN groupadd --gid $USER_GID $USERNAME \
    && useradd --uid $USER_UID --gid $USER_GID -m $USERNAME

RUN chown -R $USERNAME:root /usr/local/bin/chrome-linux
RUN ln -s /usr/local/bin/chrome-linux/chrome /usr/local/bin/chrome
RUN chrome --version

RUN mkdir $HOME || true
VOLUME $HOME
COPY --chmod=770 entrypoint.sh $HOME
RUN chown -R $USERNAME:root $HOME

RUN echo "export XDG_CACHE_HOME=$(mktemp -d)" >> /etc/bash.bashrc
RUN chown -R $USERNAME:root $(cat /etc/bash.bashrc |grep XDG_CACHE_HOME | cut -d "=" -f2 )
RUN chmod -R 770 $(cat /etc/bash.bashrc |grep XDG_CACHE_HOME | cut -d "=" -f2 )

## Default user
USER $USERNAME
ENV HOME=/data
ENV DEBUG_ADDRESS=0.0.0.0
ENV DEBUG_PORT=9222

WORKDIR $HOME
ENTRYPOINT ["./entrypoint.sh"]

以及 entrypoint.sh

#!/bin/sh
set -e

exec sh -c "chrome --headless=new --dump-dom --ignore-ssl-errors --no-sandbox https://domains.google.com/checkip"
帖子版权声明 1、本帖标题:Ubuntu 上的 Docker 化 Chromium
    本站网址:http://xjnalaquan.com/
2、本网站的资源部分来源于网络,如有侵权,请联系站长进行删除处理。
3、会员发帖仅代表会员个人观点,并不代表本站赞同其观点和对其真实性负责。
4、本站一律禁止以任何方式发布或转载任何违法的相关信息,访客发现请向站长举报
5、站长邮箱:yeweds@126.com 除非注明,本帖由seans在本站《ubuntu》版块原创发布, 转载请注明出处!
最新回复 (0)
  • 我的 Linux(SLES-8)服务器目前有 glibc-2.2.5-235,但我有一个程序无法在此版本上运行,需要 glibc-2.3.3。是否可以在同一个服务器上安装多个 glibc?...

    我的 linux(SLES-8)服务器目前有 glibc-2.2.5-235,但我有一个程序无法在此版本上运行,需要 glibc-2.3.3。

    是否可以在同一台主机上安装多个 glibc?

    这是我在旧 glibc 上运行程序时遇到的错误:

    ./myapp: /lib/i686/libc.so.6: version `GLIBC_2.3' not found (required by ./myapp)
    ./myapp: /lib/i686/libpthread.so.0: version `GLIBC_2.3.2' not found (required by ./myapp)
    ./myapp: /lib/i686/libc.so.6: version `GLIBC_2.3' not found (required by ./libxerces-c.so.27)
    ./myapp: /lib/ld-linux.so.2: version `GLIBC_2.3' not found (required by ./libstdc++.so.6)
    ./myapp: /lib/i686/libc.so.6: version `GLIBC_2.3' not found (required by ./libstdc++.so.6)
    

    因此我创建了一个名为 newglibc 的新目录并将以下文件复制到其中:

    libpthread.so.0
    libm.so.6
    libc.so.6
    ld-2.3.3.so
    ld-linux.so.2 -> ld-2.3.3.so
    

    export LD_LIBRARY_PATH=newglibc:$LD_LIBRARY_PATH
    

    但是我收到一个错误:

    ./myapp: /lib/ld-linux.so.2: version `GLIBC_PRIVATE' not found (required by ./newglibc/libpthread.so.0)
    ./myapp: /lib/ld-linux.so.2: version `GLIBC_2.3' not found (required by libstdc++.so.6)
    ./myapp: /lib/ld-linux.so.2: version `GLIBC_PRIVATE' not found (required by ./newglibc/libm.so.6)
    ./myapp: /lib/ld-linux.so.2: version `GLIBC_2.3' not found (required by ./newglibc/libc.so.6)
    ./myapp: /lib/ld-linux.so.2: version `GLIBC_PRIVATE' not found (required by ./newglibc/libc.so.6)
    

    因此看起来他们仍然链接到我放置 /lib 他们的地方,而不是从我放置他们的地方继续。

  • 我可以在 Ubuntu VPS 中安装 prestashop,但安装后无法访问网站,无论是前端还是后端。有解决方案吗?在此处输入图像描述输入图像描述...

    我可以在 Ubuntu VPS 中安装 prestashop,但安装后无法访问网站,无论是前端还是后端。

    有人有解决方案吗?

    在此处输入图片描述

    在此处输入图片描述

    我什么都试过了,希望看到前端和后端

  • 请说明您的具体问题或提供更多详细信息以准确突出您的需求。根据目前的写法,很难准确说出您要求的是什么。

  • Vin 2月前 0 只看Ta
    引用 5

    在同一个系统上很有可能存在多个版本的 glibc(我们每天都这样做)。

    但是,您需要知道 glibc 由许多部分组成(200 多个共享库),所有部分都必须匹配。其中一个部分是 ld-linux.so.2,它 必须与 libc.so.6 匹配,否则您将看到所看到的错误。

    ld-linux.so.2 的绝对路径在链接时被硬编码到可执行文件中,并且在链接完成后不能轻易更改(更新:可以使用 patchelf ;请参阅 答案 )。

    要构建可与新 glibc 一起使用的可执行文件,请执行以下操作:

    g++ main.o -o myapp ... \
       -Wl,--rpath=/path/to/newglibc \
       -Wl,--dynamic-linker=/path/to/newglibc/ld-linux.so.2
    

    链接 -rpath 器选项将使运行时加载器搜索库 /path/to/newglibc (因此您不必 LD_LIBRARY_PATH 在运行它之前进行设置),并且该 -dynamic-linker 选项将“烘焙”路径以更正 ld-linux.so.2 到应用程序中。

    如果您无法重新链接 myapp 应用程序(例如,因为它是第三方二进制文件),则不会丢失所有内容,但会变得更加棘手。一种解决方案是 chroot 为其设置适当的环境。另一种可能性是使用 rtldi 二进制编辑器 .

    更新: 或者您可以在现有二进制文件上使用 patchelf 将它们重定向到备用 libc。

  • 现在您可以使用一个方便的实用程序 patchelf (nixos.org/patchelf.html),它允许您修改已编译的 ELF 的 rpath 和解释器。

  • 值得一提的是,使用 -Wl,--rpath 而不是 LD_LIBRARY_PATH 指定新 glibc 的路径除了方便之外,还有其它重要原因:如果程序启动子进程,则 LD_LIBRARY_PATH 的值通常会被它们继承,但如果它们没有被编译为使用较新的 glibc(例如,如果它们是像 bash 这样的库存二进制文件),则它们将无法启动。

  • 另一个选择是直接运行新的 ld.so,将二进制程序作为参数传递给它;这将有效地替换 ld.so,而无需重新编译程序:/path/to/newglibc/ld-linux.so.2 --library-path /path/tonewglibc/lib64:/path/to/newglibc/usr/lib64 /path/to/myapp

  • @SantoshKale 要在 \'parallel\' 位置安装,您必须配置 --prefix /new/location 并 make && make install。预构建的 RPM 将不起作用。

  • 这个问题很老了,其他答案也很老了。Employed Russian 的答案 非常好,信息量很大,但只有当您有源代码时才有效。如果没有,当时的替代方案非常棘手。幸运的是,现在我们有一个简单的解决方案(如 他的一个回复 ),使用 patchelf 。您所要做的就是:

    $ ./patchelf --set-interpreter /path/to/newglibc/ld-linux.so.2 --set-rpath /path/to/newglibc/ myapp
    

    这将使无法正常工作的可执行文件使用不同的链接器路径。之后,你就可以执行文件了:

    $ ./myapp
    

    ,无需 chroot 手动编辑二进制文件。但是,如果您不确定自己在做什么,请记住在修补二进制文件之前备份它,因为它会修改二进制文件。修补后,您无法将旧路径恢复为解释器/rpath。如果它不起作用,您必须继续修补它,直到找到真正有效的路径……好吧,它不必是一个反复试验的过程。例如,在 OP 的例子中,他需要 GLIBC_2.3 ,因此您可以使用轻松找到哪个库提供该版本 strings

    $ strings /lib/i686/libc.so.6 | grep GLIBC_2.3
    $ strings /path/to/newglib/libc.so.6 | grep GLIBC_2.3
    

    理论上,第一个 grep 会输出空,因为系统 libc 没有他想要的版本,而第二个 grep 应该输出 GLIBC_2.3,因为它有他 myapp 想要的版本,所以我们知道我们可以 patchelf 使用该路径来执行二进制文件。如果遇到分段错误,请阅读最后的说明。

    当您尝试在 Linux 中运行二进制文件时,二进制文件会尝试加载链接器(又名加载器,又名解释器),然后加载库,它们都应该在路径中和/或正确的位置。如果您的问题出在链接器上,并且您想找出二进制文件正在寻找的路径,您可以使用以下命令查找:

    $ readelf -l myapp | grep interpreter
      [Requesting program interpreter: /lib/ld-linux.so.2]                                                                                                                                                                                   
    

    如果您的问题与库有关,则可以使用以下命令为您提供正在使用的库:

    $ readelf -d myapp | grep Shared
    $ ldd myapp 
    

    这将列出二进制文件所需的库,但您可能已经知道有问题的库,因为它们已经产生错误,就像 OP 的情况一样。执行 patchelf 后,可能 myapp 仍然无法正常工作,运行时 ldd myapp 它会列出具有混合路径的库,一些到您设置的路径,其他到原始系统路径。那是因为您的路径没有这些库。 rpath 将在您设置的路径中搜索库,但如果不存在,它仍会在其他系统位置中查找。在这种情况下,如果您在某处有缺失的库,只需将其复制到您 rpath 选择的路径,它应该就可以工作了。

    \'patchelf\' 可以解决您在尝试运行程序时可能遇到的许多不同问题,这些问题与这两个问题有关。例如,如果您得到: ELF file OS ABI invalid ,则可以通过设置新的加载器( --set-interpreter 命令的一部分)来修复,如我 在此处 运行存在且可执行的文件时 No such file or directory 出现的问题。在那个特定情况下,OP 缺少加载器的链接,但也许在您的情况下您没有 root 访问权限并且无法创建链接。设置新的解释器将解决您的问题。

    感谢 Employed Russian 和 Michael Pankov 的见解和解决方案!


    注意 事项:您可能会遇到使用多个库的情况 myapp ,其中大多数都正常,但有些不正常;然后您 patchelf 将其移至新目录,就会出现分段错误。当您 patchelf 编写二进制文件时,您会更改几个库的路径,即使有些库最初位于不同的路径中。请看下面的示例:

    $ ldd myapp
    ./myapp: /usr/lib/x86_64-linux-gnu/libstdc++.so.6: version `GLIBCXX_3.4.20' not found (required by ./myapp)
    ./myapp: /usr/lib/x86_64-linux-gnu/libstdc++.so.6: version `GLIBCXX_3.4.21' not found (required by ./myapp)
            linux-vdso.so.1 =>  (0x00007fffb167c000)
            libm.so.6 => /lib/x86_64-linux-gnu/libm.so.6 (0x00007f9a9aad2000)
            libdl.so.2 => /lib/x86_64-linux-gnu/libdl.so.2 (0x00007f9a9a8ce000)
            libpthread.so.0 => /lib/x86_64-linux-gnu/libpthread.so.0 (0x00007f9a9a6af000)
            libstdc++.so.6 => /usr/lib/x86_64-linux-gnu/libstdc++.so.6 (0x00007f9a9a3ab000)
            libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f9a99fe6000)
            /lib64/ld-linux-x86-64.so.2 (0x00007f9a9adeb000)
            libgcc_s.so.1 => /lib/x86_64-linux-gnu/libgcc_s.so.1 (0x00007f9a99dcf000)
    

    请注意,大多数库都在 中, /lib/x86_64-linux-gnu/ 但有问题的库 ( libstdc++.so.6 ) 在 上 /usr/lib/x86_64-linux-gnu 。在我将其修补 myapp 以指向 /path/到/mylibs ,我得到了分段错误。出于某种原因,这些库与二进制文件并不完全兼容。由于 myapp 没有抱怨原始库,我将它们从 复制 /lib/x86_64-linux-gnu/ to /path/to/mylibs2 ,我也 libstdc++.so.6 /path/to/mylibs 那里复制。然后我将其修补到 /path/to/mylibs2 myapp 现在可以正常工作。如果您的二进制文件使用不同的库,并且您有不同的版本,则可能无法修复您的情况。 :( 但如果可能的话,混合使用库可能是办法。这不是理想的,但 也许 会起作用。祝你好运!

  • 引用 11

    非常有用的实用程序!谢谢!虽然我花了几个小时手动解决依赖关系,然后修补所有内容以在本地安装没有管理员权限的 chrome,但只设法获得了分段错误...

  • kztd 2月前 0 只看Ta
    引用 12

    @fgiraldeau 谢谢你的赞美。:) 但这个问题是在 2009 年提出、回答和接受的,我不希望有人等 8 年才接受答案。呵呵 ;D

  • 嗨,讽刺的是,我得到了 ./patchelf: /lib64/libstdc++.so.6: 未找到版本 GLIBCXX_3.4.21(./patchelf 所需)`我想我会寻找另一个解决方案

  • patchelf 页面指向源代码,位于 github.com/NixOS/patchelf,因此理论上您可以在您的系统中编译它……但这可能会带来一系列问题。哈哈 :(

  • Ems 2月前 0 只看Ta
    引用 15

    @AlexO 您不应该修补 libc,而应该修补使用 libc 的可执行文件(通过将其指向具有您需要的版本的其他 libc)。也许可以在 StackOverflow 上发布一个新问题,其中包含您的问题的所有详细信息以及您尝试过的方法。:)

  • TIM 2月前 0 只看Ta
    引用 16

    使用 LD_PRELOAD:将您的库放在 man lib 目录之外的某个地方并运行:

    LD_PRELOAD='mylibc.so anotherlib.so' program
    

    参见: 维基百科文章

  • 我以为这对于复杂的 Makefile 来说是一个很好的解决方法,但它对我来说不起作用

  • m3n 2月前 0 只看Ta
    引用 18

    嗯...我错了,似乎我需要在源代码编译和链接时首先将 ld-linux.so rpath 到 /path/to/new/lib/

  • 如果 ld-#.##.so (来自系统 glibc lib) 与 libc.so.# (来自备用 glibc lib) 不是同一 glibc 版本,则此方法无效

  • 首先每个动态链接程序最重要的依赖就是链接器,所有的so库都必须和链接器的版本相匹配。

    让我们举一个简单的例子:我有一个新的 ubuntu 系统,我在其中运行一些程序(在我的情况下是 D 编译器 - ldc2)。我想在旧的 CentOS 上运行它,但由于较旧的 glibc 库,这是不可能的。我得到了

    ldc2-1.5.0-linux-x86_64/bin/ldc2: /lib64/libc.so.6: version `GLIBC_2.15' not found (required by ldc2-1.5.0-linux-x86_64/bin/ldc2)
    ldc2-1.5.0-linux-x86_64/bin/ldc2: /lib64/libc.so.6: version `GLIBC_2.14' not found (required by ldc2-1.5.0-linux-x86_64/bin/ldc2)
    

    我必须将所有依赖项从 ubuntu 复制到 centos。正确的方法如下:

    首先,让我们检查所有依赖项:

    ldd ldc2-1.5.0-linux-x86_64/bin/ldc2 
        linux-vdso.so.1 =>  (0x00007ffebad3f000)
        librt.so.1 => /lib/x86_64-linux-gnu/librt.so.1 (0x00007f965f597000)
        libpthread.so.0 => /lib/x86_64-linux-gnu/libpthread.so.0 (0x00007f965f378000)
        libz.so.1 => /lib/x86_64-linux-gnu/libz.so.1 (0x00007f965f15b000)
        libdl.so.2 => /lib/x86_64-linux-gnu/libdl.so.2 (0x00007f965ef57000)
        libm.so.6 => /lib/x86_64-linux-gnu/libm.so.6 (0x00007f965ec01000)
        libgcc_s.so.1 => /lib/x86_64-linux-gnu/libgcc_s.so.1 (0x00007f965e9ea000)
        libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f965e60a000)
        /lib64/ld-linux-x86-64.so.2 (0x00007f965f79f000)
    

    linux-vdso.so.1 不是一个真正的库,我们不必关心它。

    /lib64/ld-linux-x86-64.so.2 是链接器,linux使用它来将可执行文件与所有动态库链接起来。

    其余文件是真正的库,所有文件连同链接器都必须复制到 centos 中的某个地方。

    我们假设所有库和链接器都在'/mylibs'目录中。

    ld-linux-x86-64.so.2 - 我已经说过了 - 是链接器。它不是动态库,而是静态可执行文件。您可以运行它,并看到它甚至有一些参数,例如 --library-path(我将返回到它)。

    在Linux上,动态链接程序可能仅通过其名称启动,例如

    /bin/ldc2
    

    Linux 会将此类程序加载到 RAM 中,并检查为其设置了哪个链接器。通常在 64 位系统上,它是 /lib64/ld-linux-x86-64.so.2(在您的文件系统中,它是指向实际可执行文件的符号链接)。然后 Linux 运行链接器并加载动态库。

    您也可以稍微改变一下,做这样的技巧:

    /mylibs/ld-linux-x86-64.so.2 /bin/ldc2
    

    这是强制Linux使用特定链接器的方法。

    现在我们可以回到前面提到的参数--library-path

    /mylibs/ld-linux-x86-64.so.2 --library-path /mylibs /bin/ldc2
    

    它将运行 ldc2 并从 /mylibs 加载动态库。

    这是使用选定的(非系统默认的)库调用可执行文件的方法。

返回
作者最近主题: