Rod 在 Docker Alpine 中运行得到错误“chrome-linux/chrome:没有这样的文件或目录”

Posted

技术标签:

【中文标题】Rod 在 Docker Alpine 中运行得到错误“chrome-linux/chrome:没有这样的文件或目录”【英文标题】:Rod Running In Docker Alpine Get Error "chrome-linux/chrome: no such file or directory" 【发布时间】:2022-01-12 04:51:58 【问题描述】:

我正在使用 golang/rod 来做类似 puppeteer 的事情。

在我的开发 PC 中一切正常,但在我 docker build 并在 alpine 中运行后,它得到以下错误:

chrome-linux/chrome: 没有这样的文件或目录

错误信息

Download: https://npm.taobao.org/mirrors/chromium-browser-snapshots/Linux_x64/901912/chrome-linux.zip
Progress: 00% 16% 24% 33% 41% 49% 58% 66% 74% 83% 91% 99% 100%
Unzip to: /root/.cache/rod/browser/chromium-901912
Progress: 00% 21% 37% 63% 92% 100%

2021/12/07 11:22:18 [Recovery] 2021/12/07 - 11:22:18 panic recovered:

fork/exec /root/.cache/rod/browser/chromium-901912/chrome-linux/chrome: no such file or directory
/go/pkg/mod/github.com/go-rod/rod@v0.101.8/lib/utils/utils.go:64 (0xa41a24)
/go/pkg/mod/github.com/go-rod/rod@v0.101.8/must.go:35 (0xb02679)
/go/pkg/mod/github.com/go-rod/rod@v0.101.8/must.go:50 (0xb02828)
/go/src/app/bscase/service.go:733 (0xb38c6c)
/go/pkg/mod/github.com/gin-gonic/gin@v1.7.3/context.go:165 (0x999d92)
/go/src/app/common/api/middleware.go:26 (0x999d7a)
/go/pkg/mod/github.com/gin-gonic/gin@v1.7.3/context.go:165 (0x98fee1)
/go/pkg/mod/github.com/gin-gonic/gin@v1.7.3/recovery.go:99 (0x98fecc)
/go/pkg/mod/github.com/gin-gonic/gin@v1.7.3/context.go:165 (0x98f146)
/go/pkg/mod/github.com/gin-gonic/gin@v1.7.3/logger.go:241 (0x98f129)
/go/pkg/mod/github.com/gin-gonic/gin@v1.7.3/context.go:165 (0x98e67d)
/go/pkg/mod/github.com/gin-gonic/gin@v1.7.3/gin.go:489 (0x98e305)
/go/pkg/mod/github.com/gin-gonic/gin@v1.7.3/gin.go:445 (0x98de64)
/usr/local/go/src/net/http/server.go:2878 (0x6ddcfa)
/usr/local/go/src/net/http/server.go:1929 (0x6d93a7)
/usr/local/go/src/runtime/asm_amd64.s:1581 (0x4632c0)

Go代码(1.17版,棒版v0.101.8)

l, _ := launcher.New().Set("disable-web-security").
        Set("disable-setuid-sandbox").
        Set("no-sandbox").
        Set("no-first-run", "true").
        Set("disable-gpu").
        Headless(true).
        Launch()
browser := rod.New().ControlURL(l).MustConnect()

dockerfile

FROM golang:1.17 AS builder

ENV GO111MODULE=on \
    GOPROXY="https://mirrors.aliyun.com/goproxy/,direct"

WORKDIR $GOPATH/src/app

# manage dependencies
COPY go.mod ./
COPY go.sum ./
RUN go mod download

COPY . .
RUN CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build -a -o /app .

FROM alpine:latest  
# Install base packages
RUN sed -i 's/dl-cdn.alpinelinux.org/mirrors.aliyun.com/g' /etc/apk/repositories
RUN apk update
RUN apk upgrade
RUN apk add --no-cache chromium
WORKDIR /root/
COPY --from=builder /app ./
COPY /configs ./configs
CMD ["./app"]  

Rod 文档说 apk add chromium 可以修复,但它在我的容器中不起作用。

【问题讨论】:

【参考方案1】:

/root/.cache/rod/browser/chromium-901912/chrome-linux/chrome: 没有这样的文件或目录

这是因为go-rod 如果找不到有效的二进制文件,他会从 Internet 下载预构建的浏览器二进制文件。

不幸的是,预建的是用 glibc 构建的,而 alpine 使用 muslc,这是您看到 no such file or directory 的根本原因,因为预建的与 alpine 不兼容。

是的,来自its doc,它说:

在阿尔卑斯山:

apk add chromium

但是,您还需要更改您的应用程序代码,让go-rod 明确找到浏览器,否则它仍然会尝试使用互联网上的浏览器,详情请参阅this。

一个简单的 go 文件:

test.go:

package main

import (
    "github.com/go-rod/rod"
    "github.com/go-rod/rod/lib/launcher"
)

func main() 
    path, _ := launcher.LookPath()
    u := launcher.New().Bin(path).MustLaunch()
    rod.New().ControlURL(u).MustConnect().MustPage("https://www.baidu.com/")
    // rod.New().MustConnect().MustPage("https://www.baidu.com/")

通过上面,它会尝试找到你用apk add安装的chromium,然后没有错误。

【讨论】:

以上是关于Rod 在 Docker Alpine 中运行得到错误“chrome-linux/chrome:没有这样的文件或目录”的主要内容,如果未能解决你的问题,请参考以下文章

Docker:如何知道 mongo 是不是在 Alpine/node 中使用 shell 脚本文件运行

无法在基于 Alpine 的 Docker 容器中运行 Play 框架应用程序

如何让 /etc/profile 在 Alpine / Docker 中自动运行

在 Alpine Docker 容器中运行 OpenSSH

无法使用 node:alpine 在 Docker 容器中运行 React 应用程序的开发版本

如何在 Alpine Docker 容器中运行 Bash 脚本?