我有一个Golang代码,它使用chromedp连接到用户的本地Chrome 以下是我的代码:

package main

import (
    "context"
    "fmt"
    "log"
    "os"
    "time"

    "github.com/chromedp/chromedp"
    "github.com/gin-gonic/gin"
)

func main() {
    Api := gin.Default()

    Api.GET("api/jwt", func(c *gin.Context) {
        opts := append(chromedp.DefaultExecAllocatorOptions[:],
            chromedp.Flag("headless", false),
            chromedp.Flag("disable-gpu", true),
            chromedp.Flag("no-sandbox", true),
            chromedp.Flag("disable-dev-shm-usage", true),
            chromedp.Flag("disable-browser-side-navigation", true),
            chromedp.Flag("disable-infobars", true),
            chromedp.Flag("disable-extensions", true),
            chromedp.Flag("disable-notifications", true),
            chromedp.Flag("disable-default-apps", true),
            chromedp.Flag("disable-background-timer-throttling", true),
            chromedp.Flag("disable-backgrounding-occluded-windows", true),
            chromedp.Flag("disable-renderer-backgrounding", true),
        )

        allocCtx, cancel := chromedp.NewExecAllocator(context.Background(), opts...)
        defer cancel()

        ctx, cancel := chromedp.NewContext(allocCtx)
        defer cancel()

        var localStorageData string // Declaração da variável localStorageData

        err := chromedp.Run(ctx,
            chromedp.Navigate("https://csonlinetenant.b2clogin.com/csonlinetenant.onmicrosoft.com/oauth2/v2.0/authorize"),
            chromedp.Sleep(5*time.Second),
            chromedp.WaitVisible(`#fgh`),
            chromedp.SendKeys(`#fghfg`, "fghfgh"),
            chromedp.SendKeys(`#xcvxcv`, "xcxcvcxv"),
            chromedp.Click(`#thgh`, chromedp.ByID),
            chromedp.Sleep(5*time.Second),
            chromedp.Click(`dfgd`, chromedp.ByID),
            chromedp.Sleep(15*time.Second),
            chromedp.EvaluateAsDevTools(`localStorage.getItem('c')`, &localStorageData),
        )
        if err != nil {
            log.Printf("Error: %v", err)
            return
        }

        fmt.Println("Bearer", localStorageData)

        // Restante do código...

        c.JSON(200, gin.H{
            "Success": localStorageData,
        })
    })

    listenAddr := os.Getenv("LISTEN")

    if val, ok := os.LookupEnv("FUNCTIONS_CUSTOMHANDLER_PORT"); ok {
        listenAddr = ":" + val
    }
    if listenAddr == "" {
        listenAddr = ":8080"
    }

    Api.Run(listenAddr)
}

因此,我制作了一个dockerfile,其中包含了我的客户使用该应用程序所需的内容(我安装了Chrome并在图像中构建了我的Golang)

文档文件:

FROM golang:1.20 AS build-stage

WORKDIR /app

# Instale as dependências do Chrome
RUN wget -q -O - https://dl-ssl.google.com/linux/linux_signing_key.pub | apt-key add - \
    && echo "deb http://dl.google.com/linux/chrome/deb/ stable main" >> /etc/apt/sources.list.d/google.list
RUN apt-get update && apt-get -y install google-chrome-stable
RUN chrome &


COPY go.mod go.sum ./
RUN go mod download

COPY *.go ./

RUN CGO_ENABLED=0 GOOS=linux go build -o /dockergo

# Run the tests in the container
FROM build-stage AS run-test-stage
RUN go test -v ./...

# Deploy the application binary into a lean image
FROM gcr.io/distroless/base-debian11 AS build-release-stage

WORKDIR /

COPY --from=build-stage /dockergo /dockergo

EXPOSE 8080

USER nonroot:nonroot

ENTRYPOINT ["/dockergo"]

成功地构建了映像,并且没有令人头疼的问题 但是,当在本地测试docker映像时,我收到以下错误:

 Error: exec: "google-chrome": executable file not found in $PATH

这个错误是什么意思?我的 chromium 合金没有运行吗?我怎么才能经营它呢?

推荐答案

Chrome浏览器仅安装在build-stage中.这在build-release-stage创建的最终图像中是不可用的.

我try 使用此Dockerfile安装Chrome:

# Deploy the application binary into a lean image
FROM gcr.io/distroless/base-debian11 AS build-release-stage

RUN wget -q -O - https://dl-ssl.google.com/linux/linux_signing_key.pub | apt-key add - \
    && echo "deb http://dl.google.com/linux/chrome/deb/ stable main" >> /etc/apt/sources.list.d/google.list
RUN apt-get update && apt-get -y install google-chrome-stable
RUN chrome &

但它失败了,并显示以下消息:

...
Step 2/4 : RUN wget -q -O - https://dl-ssl.google.com/linux/linux_signing_key.pub | apt-key add -     && echo "deb http://dl.google.com/linux/chrome/deb/ stable main" >> /etc/apt/sources.list.d/google.list
 ---> Running in 7596202a5684
failed to create shim task: OCI runtime create failed: runc create failed: unable to start container process: exec: "/bin/sh": stat /bin/sh: no such file or directory: unknown

我认为你必须 Select 另一个容易安装Chrome的基础镜像.更好的替代方法是使用chromedp/headless-shell作为基本图像.这张图片包含了Chrome的无头shell ,它非常小.下面的演示Docker文件还显示了首先编译测试二进制文件,然后在chromedp/headless-shell镜像中运行测试:

FROM golang:1.20.5-buster AS build-stage

WORKDIR /app

COPY go.mod go.sum ./
RUN go mod download

COPY . .

RUN CGO_ENABLED=0 go build -o dockergo
# Build the test binary
RUN CGO_ENABLED=0 go test -c -o dockergo.test

# Run the tests in the container
FROM chromedp/headless-shell:114.0.5735.199 AS run-test-stage

WORKDIR /app
# Copy other files that is needed to run the test (testdata?).
COPY . .
COPY --from=build-stage /app/dockergo.test ./dockergo.test
RUN /app/dockergo.test -test.v

# Deploy the application binary into a lean image
FROM chromedp/headless-shell:114.0.5735.199 AS build-release-stage

COPY --from=build-stage /app/dockergo /dockergo

EXPOSE 8080

ENTRYPOINT ["/dockergo"]

Go相关问答推荐

golang父进程的副本无法进行https/tls调用并获得tls:未能验证证书""

Go Fiber和HTMX—HX—Trigger header被更改为HX—Trigger,这不是HTMX监听的内容

Go程序在并发Forking 循环中停留在syscall.Wait4

golang 的通用 map 功能

Go SQLCMD比Windows本机版本慢吗?

包裹网.Conn导致挂起读取

可以';t从主机连接到ScyllaDB容器

如何使用 Go 连接到非默认 firestore 数据库?

为什么 Go 对于长度为 100k 的切片使用的内存比长度为 100k 的数组要少?

是否需要手动调用rand.Seed?

使用GOTK3和librsvg在Go中如何加载内联SVG?

如何测试光纤参数

泛型:实现嵌套接口

将值发送到 Channel 并在就绪时读取输出

在 Go 中公开公共 JWK

仅在工作日运行 cron

Golang Getrlimit 返回与 ulimit 不同的值

如何获取多个 url 参数值

如何在 Windows 上使用 cgo 为 386 arch 构建 lib?

带有 *s3.S3 对象的 Golang 单元测试