You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Golang+chromedp Docker部署报错:google-chrome不在$PATH中

问题与解决方案

问题描述

使用chromedp连接Chrome的Golang代码,搭配包含Chrome安装步骤的Dockerfile构建镜像成功,但运行镜像时出现exec: "google-chrome": executable file not found in $PATH错误。

相关代码

Golang代码

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

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"]

错误信息

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


错误含义与解决方法

错误含义

该错误表示chromedp尝试调用google-chrome可执行文件,但当前运行的容器系统中,$PATH环境变量下找不到这个程序。不是Chrome未运行,是Chrome根本没有安装在最终运行的镜像里。

原因分析

  1. Docker采用多阶段构建,最终运行的gcr.io/distroless/base-debian11是极简镜像,仅包含最基础的系统组件,没有复制build-stage阶段安装的Google Chrome及相关依赖。
  2. build-stage中的RUN chrome &完全无效:构建阶段启动的进程在构建完成后会立即终止,且该命令本身可能因缺少终端环境导致构建警告或失败。

解决方法

方案一:改用包含Chrome的基础镜像(推荐,操作简单)

放弃distroless极简镜像,直接使用已安装Chrome的build-stage镜像作为最终运行环境,修改Dockerfile的build-release-stage部分:

FROM golang:1.20 AS build-stage

WORKDIR /app

# 安装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

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

COPY *.go ./

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

# 测试阶段
FROM build-stage AS run-test-stage
RUN go test -v ./...

# 最终运行镜像,复用已安装Chrome的build-stage环境
FROM build-stage AS build-release-stage

WORKDIR /

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

EXPOSE 8080

USER nonroot:nonroot

ENTRYPOINT ["/dockergo"]

方案二:将Chrome及依赖复制到distroless镜像(保持镜像精简,操作复杂)

如果坚持使用distroless镜像,需要手动复制Chrome可执行文件和必要的系统依赖库到最终镜像:

FROM golang:1.20 AS build-stage

WORKDIR /app

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

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

COPY *.go ./

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

FROM gcr.io/distroless/base-debian11 AS build-release-stage

WORKDIR /

# 复制Chrome可执行文件和安装目录
COPY --from=build-stage /usr/bin/google-chrome /usr/bin/google-chrome
COPY --from=build-stage /opt/google /opt/google

# 复制Chrome运行必需的系统依赖库(根据实际运行情况补充)
COPY --from=build-stage /lib/x86_64-linux-gnu/libnss3.so /lib/x86_64-linux-gnu/libnss3.so
COPY --from=build-stage /lib/x86_64-linux-gnu/libnssutil3.so /lib/x86_64-linux-gnu/libnssutil3.so
COPY --from=build-stage /lib/x86_64-linux-gnu/libsmime3.so /lib/x86_64-linux-gnu/libsmime3.so
COPY --from=build-stage /lib/x86_64-linux-gnu/libssl3.so /lib/x86_64-linux-gnu/libssl3.so
COPY --from=build-stage /lib/x86_64-linux-gnu/libcrypto.so.1.1 /lib/x86_64-linux-gnu/libcrypto.so.1.1
COPY --from=build-stage /lib/x86_64-linux-gnu/libglib-2.0.so.0 /lib/x86_64-linux-gnu/libglib-2.0.so.0

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

EXPOSE 8080

USER nonroot:nonroot

ENTRYPOINT ["/dockergo"]

额外优化建议

容器环境下不适合运行非无头模式的Chrome,建议将Golang代码中的headless参数改为true:

chromedp.Flag("headless", true),

内容的提问来源于stack exchange,提问作者Guilherme Rodrigues

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.17 13:02:20