英文:
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.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。


评论