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

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

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

问题

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

在我的开发电脑上一切正常,但是在使用docker build构建并在alpine中运行后,出现以下错误:

chrome-linux/chrome: 没有该文件或目录

错误信息

  1. Download: https://npm.taobao.org/mirrors/chromium-browser-snapshots/Linux_x64/901912/chrome-linux.zip
  2. Progress: 00% 16% 24% 33% 41% 49% 58% 66% 74% 83% 91% 99% 100%
  3. Unzip to: /root/.cache/rod/browser/chromium-901912
  4. Progress: 00% 21% 37% 63% 92% 100%
  5. 2021/12/07 11:22:18 [Recovery] 2021/12/07 - 11:22:18 panic recovered:
  6. fork/exec /root/.cache/rod/browser/chromium-901912/chrome-linux/chrome: no such file or directory
  7. /go/pkg/mod/github.com/go-rod/rod@v0.101.8/lib/utils/utils.go:64 (0xa41a24)
  8. /go/pkg/mod/github.com/go-rod/rod@v0.101.8/must.go:35 (0xb02679)
  9. /go/pkg/mod/github.com/go-rod/rod@v0.101.8/must.go:50 (0xb02828)
  10. /go/src/app/bscase/service.go:733 (0xb38c6c)
  11. /go/pkg/mod/github.com/gin-gonic/gin@v1.7.3/context.go:165 (0x999d92)
  12. /go/src/app/common/api/middleware.go:26 (0x999d7a)
  13. /go/pkg/mod/github.com/gin-gonic/gin@v1.7.3/context.go:165 (0x98fee1)
  14. /go/pkg/mod/github.com/gin-gonic/gin@v1.7.3/recovery.go:99 (0x98fecc)
  15. /go/pkg/mod/github.com/gin-gonic/gin@v1.7.3/context.go:165 (0x98f146)
  16. /go/pkg/mod/github.com/gin-gonic/gin@v1.7.3/logger.go:241 (0x98f129)
  17. /go/pkg/mod/github.com/gin-gonic/gin@v1.7.3/context.go:165 (0x98e67d)
  18. /go/pkg/mod/github.com/gin-gonic/gin@v1.7.3/gin.go:489 (0x98e305)
  19. /go/pkg/mod/github.com/gin-gonic/gin@v1.7.3/gin.go:445 (0x98de64)
  20. /usr/local/go/src/net/http/server.go:2878 (0x6ddcfa)
  21. /usr/local/go/src/net/http/server.go:1929 (0x6d93a7)
  22. /usr/local/go/src/runtime/asm_amd64.s:1581 (0x4632c0)

Go代码(版本1.17,rod版本v0.101.8)

  1. l, _ := launcher.New().Set("disable-web-security").
  2. Set("disable-setuid-sandbox").
  3. Set("no-sandbox").
  4. Set("no-first-run", "true").
  5. Set("disable-gpu").
  6. Headless(true).
  7. Launch()
  8. browser := rod.New().ControlURL(l).MustConnect()

Dockerfile

  1. FROM golang:1.17 AS builder
  2. ENV GO111MODULE=on \
  3. GOPROXY="https://mirrors.aliyun.com/goproxy/,direct"
  4. WORKDIR $GOPATH/src/app
  5. # 管理依赖
  6. COPY go.mod ./
  7. COPY go.sum ./
  8. RUN go mod download
  9. COPY . .
  10. RUN CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build -a -o /app .
  11. FROM alpine:latest
  12. # 安装基本软件包
  13. RUN sed -i 's/dl-cdn.alpinelinux.org/mirrors.aliyun.com/g' /etc/apk/repositories
  14. RUN apk update
  15. RUN apk upgrade
  16. RUN apk add --no-cache chromium
  17. WORKDIR /root/
  18. COPY --from=builder /app ./
  19. COPY /configs ./configs
  20. 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

  1. Download: https://npm.taobao.org/mirrors/chromium-browser-snapshots/Linux_x64/901912/chrome-linux.zip
  2. Progress: 00% 16% 24% 33% 41% 49% 58% 66% 74% 83% 91% 99% 100%
  3. Unzip to: /root/.cache/rod/browser/chromium-901912
  4. Progress: 00% 21% 37% 63% 92% 100%
  5. 2021/12/07 11:22:18 [Recovery] 2021/12/07 - 11:22:18 panic recovered:
  6. fork/exec /root/.cache/rod/browser/chromium-901912/chrome-linux/chrome: no such file or directory
  7. /go/pkg/mod/github.com/go-rod/rod@v0.101.8/lib/utils/utils.go:64 (0xa41a24)
  8. /go/pkg/mod/github.com/go-rod/rod@v0.101.8/must.go:35 (0xb02679)
  9. /go/pkg/mod/github.com/go-rod/rod@v0.101.8/must.go:50 (0xb02828)
  10. /go/src/app/bscase/service.go:733 (0xb38c6c)
  11. /go/pkg/mod/github.com/gin-gonic/gin@v1.7.3/context.go:165 (0x999d92)
  12. /go/src/app/common/api/middleware.go:26 (0x999d7a)
  13. /go/pkg/mod/github.com/gin-gonic/gin@v1.7.3/context.go:165 (0x98fee1)
  14. /go/pkg/mod/github.com/gin-gonic/gin@v1.7.3/recovery.go:99 (0x98fecc)
  15. /go/pkg/mod/github.com/gin-gonic/gin@v1.7.3/context.go:165 (0x98f146)
  16. /go/pkg/mod/github.com/gin-gonic/gin@v1.7.3/logger.go:241 (0x98f129)
  17. /go/pkg/mod/github.com/gin-gonic/gin@v1.7.3/context.go:165 (0x98e67d)
  18. /go/pkg/mod/github.com/gin-gonic/gin@v1.7.3/gin.go:489 (0x98e305)
  19. /go/pkg/mod/github.com/gin-gonic/gin@v1.7.3/gin.go:445 (0x98de64)
  20. /usr/local/go/src/net/http/server.go:2878 (0x6ddcfa)
  21. /usr/local/go/src/net/http/server.go:1929 (0x6d93a7)
  22. /usr/local/go/src/runtime/asm_amd64.s:1581 (0x4632c0)

Go code (version 1.17, rod version v0.101.8)

  1. l, _ := launcher.New().Set("disable-web-security").
  2. Set("disable-setuid-sandbox").
  3. Set("no-sandbox").
  4. Set("no-first-run", "true").
  5. Set("disable-gpu").
  6. Headless(true).
  7. Launch()
  8. browser := rod.New().ControlURL(l).MustConnect()

dockerfile

  1. FROM golang:1.17 AS builder
  2. ENV GO111MODULE=on \
  3. GOPROXY="https://mirrors.aliyun.com/goproxy/,direct"
  4. WORKDIR $GOPATH/src/app
  5. # manage dependencies
  6. COPY go.mod ./
  7. COPY go.sum ./
  8. RUN go mod download
  9. COPY . .
  10. RUN CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build -a -o /app .
  11. FROM alpine:latest
  12. # Install base packages
  13. RUN sed -i 's/dl-cdn.alpinelinux.org/mirrors.aliyun.com/g' /etc/apk/repositories
  14. RUN apk update
  15. RUN apk upgrade
  16. RUN apk add --no-cache chromium
  17. WORKDIR /root/
  18. COPY --from=builder /app ./
  19. COPY /configs ./configs
  20. 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:

  1. package main
  2. import (
  3. "github.com/go-rod/rod"
  4. "github.com/go-rod/rod/lib/launcher"
  5. )
  6. func main() {
  7. path, _ := launcher.LookPath()
  8. u := launcher.New().Bin(path).MustLaunch()
  9. rod.New().ControlURL(u).MustConnect().MustPage("https://www.baidu.com/")
  10. // rod.New().MustConnect().MustPage("https://www.baidu.com/")
  11. }

使用上述代码,它将尝试找到你使用 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:

  1. package main
  2. import (
  3. "github.com/go-rod/rod"
  4. "github.com/go-rod/rod/lib/launcher"
  5. )
  6. func main() {
  7. path, _ := launcher.LookPath()
  8. u := launcher.New().Bin(path).MustLaunch()
  9. rod.New().ControlURL(u).MustConnect().MustPage("https://www.baidu.com/")
  10. // rod.New().MustConnect().MustPage("https://www.baidu.com/")
  11. }

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:

确定