在Docker Alpine中运行Rod时出现错误:“chrome-linux/chrome: 没有该文件或目录”。

huangapple go评论79阅读模式
英文:

Rod Running In Docker Alpine Get Error "chrome-linux/chrome: no such file or directory"

问题

我正在使用golang/rod来实现类似于puppeteer的功能。

在我的开发电脑上一切正常,但是在使用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,rod版本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

# 管理依赖
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  
# 安装基本软件包
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可以解决问题,但在我的容器中没有起作用。

英文:

I'm using golang/rod to do something like puppeteer.

Everything is ok in my dev pc, but after I docker build and run in alpine it gets the following error:

> chrome-linux/chrome: no such file or directory

Error Info

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 code (version 1.17, rod version 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"]  

The Rod documentation says apk add chromium can fix but it didn't work in my container.

答案1

得分: 2

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

这是因为 go-rod 如果找不到有效的浏览器,会从互联网上下载一个预编译的浏览器二进制文件。

不幸的是,预编译的浏览器是使用 glibc 构建的,而 alpine 使用 muslc,这就是你看到 没有这个文件或目录 的根本原因,因为预编译的浏览器与 alpine 不兼容。

是的,从 它的文档 中可以看到:

> 在 Alpine 上:
>
> apk add chromium

但是,你还需要更改你的应用程序代码,让 go-rod 显式地找到浏览器,否则它仍然会尝试使用互联网上的浏览器,详细信息请参见 这里

一个简单的 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,然后就不会出现错误了。

英文:

> /root/.cache/rod/browser/chromium-901912/chrome-linux/chrome: no such file or directory

This is because go-rod will downloads a prebuilt browser binary from internet if he can't find a valid one.

Unfortunately, the prebuilt one is built with glibc, while alpine use muslc, this is the root cause you see no such file or directory, as that prebuilt one not compatiable with alpine.

YES, from its doc, it said:

> On Alpine:
>
> apk add chromium

But, you will also need to change your application code to let go-rod to find the brower explicitly, otherwise it will still try to use the one on internet, detail see this.

A simple go file:

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/")
}

With above, it will try to find the chromium you installed with apk add, then no error.

huangapple
  • 本文由 发表于 2021年12月7日 11:38:16
  • 转载请务必保留本文链接:https://go.coder-hub.com/70254649.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定