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

Viewed 847

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 Answers

/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.

Related