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

Docker运行Java Selenium应用报错及两种部署方案咨询

问题解答:Docker部署Java Selenium应用的NoSuchDriverException及两种部署方案对比

一、当前Docker构建的核心问题

你的Dockerfile采用多阶段构建,但builder阶段安装的Chrome、ChromeDriver并未复制到最终运行的eclipse-temurin镜像中,导致运行容器内既无Chrome浏览器,也无ChromeDriver。Selenium 4.x的Selenium Manager尝试自动下载ChromeDriver时,因容器网络限制或缺少依赖工具(如curl、wget)出现超时,抛出NoSuchDriverException。

此外Dockerfile还存在两处小问题:

  • RUN apt update -y & apt install -y wget unzip 中的&应改为&&,否则命令异步执行,可能导致后续依赖工具未安装完成
  • 最终镜像复制了大量不必要文件(如src、maven目录),大幅增大镜像体积

二、修正Docker构建与ChromeDriver配置

方案1:调整多阶段构建,复制浏览器与驱动到运行镜像

修改Dockerfile,在运行阶段安装Chrome及依赖,确保容器内有完整的浏览器环境:

# builder阶段:构建应用
FROM maven:3.9.6-eclipse-temurin-17-alpine AS builder
WORKDIR /app
COPY . .
RUN mvn package -DskipTests

# runtime阶段:运行应用,安装Chrome和依赖
FROM eclipse-temurin:17.0.6_10-jdk@sha256:13817c2faa739c0351f97efabed0582a26e9e6745a6fb9c47d17f4365e56327d
WORKDIR /app

# 安装Chrome及依赖工具
ARG DEBIAN_FRONTEND=noninteractive
RUN apt-get update && apt-get install -y --no-install-recommends \
    wget unzip curl tzdata \
    google-chrome-stable && \
    rm -rf /var/lib/apt/lists/*

# 下载与Chrome版本匹配的ChromeDriver
RUN CHROME_VERSION=$(google-chrome --version | grep -oP '\d+\.\d+\.\d+\.\d+') && \
    DRIVER_VERSION=$(curl -s "https://chromedriver.storage.googleapis.com/LATEST_RELEASE_${CHROME_VERSION%.*}") && \
    wget -O /tmp/chromedriver.zip "https://chromedriver.storage.googleapis.com/${DRIVER_VERSION}/chromedriver_linux64.zip" && \
    unzip /tmp/chromedriver.zip -d /usr/local/bin/ && \
    chmod +x /usr/local/bin/chromedriver && \
    rm /tmp/chromedriver.zip

# 复制构建好的jar包及必要配置文件
COPY --from=builder /app/target/report-automation.jar .
COPY src/main/resources/config.properties .
COPY Configuration.xlsm .
COPY testng.xml .
COPY application.properties .

# 创建必要目录
RUN mkdir -p report Downloads Logs Reports

EXPOSE 8080
ENTRYPOINT ["java", "-jar", "report-automation.jar"]

方案2:代码层指定驱动路径,禁用自动下载

在Java代码中手动指定Chrome和ChromeDriver的路径,避免Selenium Manager尝试网络下载:

public ChromeOptions getOptions() {
    ChromeOptions options = new ChromeOptions();
    Map<String, String> prefs = new HashMap<>();
    prefs.put("download.default_directory", config.getProperty("absoluteDownloadLocation"));
    options.setExperimentalOption("prefs", prefs);
    // 添加容器环境无头模式必需参数
    options.addArguments("--remote-allow-origins=*");
    options.addArguments("--headless=new"); // Selenium 4.11+推荐的新无头模式
    options.addArguments("--no-sandbox"); // 容器环境必需,绕过安全沙箱
    options.addArguments("--disable-dev-shm-usage"); // 解决容器内存不足问题
    options.addArguments("--disable-gpu"); // 无头模式禁用GPU
    // 指定Chrome二进制文件路径
    options.setBinary("/usr/bin/google-chrome");
    return options;
}

@BeforeClass
public void openBrowser() throws InterruptedException {
    // 指定ChromeDriver路径
    System.setProperty("webdriver.chrome.driver", "/usr/local/bin/chromedriver");
    driver = new ChromeDriver(getOptions());
    driver.manage().window().setSize(new Dimension(1920, 1080)); // 替代maximize,无头模式更可靠
    driver.manage().timeouts().implicitlyWait(Duration.ofSeconds(10));
}

三、通过selenium/standalone-chrome集成容器

可以采用多容器架构,将Java应用与Selenium Chrome服务分离,实现解耦:

1. 编写docker-compose.yml

version: '3.8'
services:
  selenium-chrome:
    image: selenium/standalone-chrome:120.0
    shm_size: '2g' # 解决Chrome内存不足问题
    ports:
      - "4444:4444"
      - "7900:7900" # VNC端口,可查看浏览器界面(密码secret)

  app:
    build: .
    depends_on:
      - selenium-chrome
    environment:
      - SELENIUM_REMOTE_URL=http://selenium-chrome:4444/wd/hub
    volumes:
      - ./report:/app/report
      - ./Downloads:/app/Downloads

2. 修改Java代码使用RemoteWebDriver

@BeforeClass
public void openBrowser() throws InterruptedException {
    ChromeOptions options = getOptions();
    // 连接远程Selenium服务
    driver = new RemoteWebDriver(new URL(System.getenv("SELENIUM_REMOTE_URL")), options);
    driver.manage().window().setSize(new Dimension(1920, 1080));
    driver.manage().timeouts().implicitlyWait(Duration.ofSeconds(10));
}

四、两种方案对比

维度单容器(应用+浏览器)多容器(应用+selenium standalone)
部署复杂度低,单镜像部署中等,需Docker Compose管理多容器
镜像体积大(包含浏览器)小(应用镜像仅含Java环境)
维护成本高,需手动同步浏览器与驱动版本低,直接使用官方Selenium镜像,版本同步由官方维护
扩展性差,单容器资源受限好,可独立扩容Selenium服务节点
调试便利性中等,需进入容器调试高,可通过VNC端口直接查看浏览器界面

推荐场景:

  • 简单自动化任务、小规模部署:选择单容器方案,部署便捷
  • 大规模自动化测试、持续集成环境:选择多容器方案,解耦架构更易维护和扩展

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.01 13:44:54