Docker中运行Selenium报错:Server terminated early with status 255
Docker中运行Selenium报错Server terminated early with status 255的排查与解决
问题描述
执行命令 docker run --name selenium-docker --rm selenium-docker 后出现以下错误:
Run check Selenium Manager binary found at /app/node_modules/selenium-webdriver/bin/linux/selenium-manager Driver path: /root/.cache/selenium/chromedriver/linux64/117.0.5938.149/chromedriver Browser path: /root/.cache/selenium/chrome/linux64/117.0.5938.149/chrome /app/node_modules/selenium-webdriver/remote/index.js:259 reject(Error(e.message)) ^ Error: Server terminated early with status 255 at /app/node_modules/selenium-webdriver/remote/index.js:259:24 at process.processTicksAndRejections (node:internal/process/task_queues:95:5) Node.js v20.8.0
本地运行index.js正常,但Docker环境下报错。相关代码文件如下:
index.js
const {Builder, Browser} = require('selenium-webdriver'); const chrome = require('selenium-webdriver/chrome'); const userAgent = 'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/60.0.3112.50 Safari/537.36' const check = async () => { console.log('Run check') const chromeOptions = new chrome.Options(); const driver = new Builder() .forBrowser(Browser.CHROME) .setChromeOptions( chromeOptions .addArguments('--ignore-ssl-errors=yes') .addArguments('--ignore-certificate-errors') .addArguments('--no-sandbox') .addArguments('--headless=new') .addArguments('--window-size=1920,1080') .addArguments(`user-agent=${userAgent}`) ) .build(); await driver.get('https://www.google.com'); console.log('loaded!'); }
Dockerfile
FROM node:20-alpine WORKDIR /app COPY package*.json ./ RUN npm ci COPY . . CMD ["npm", "start"]
问题原因及解决方法
1. Alpine镜像缺少Chrome运行依赖
Alpine是轻量级镜像,默认没有Chrome运行所需的系统库(如glibc、libstdc++等),导致Chrome启动失败返回状态255。
解决方法:
修改Dockerfile,添加必要的依赖包:
FROM node:20-alpine # 添加Chrome运行依赖 RUN apk add --no-cache \ chromium \ chromium-chromedriver \ nss \ freetype \ harfbuzz \ ca-certificates \ ttf-freefont # 设置环境变量,指定Chrome和Chromedriver路径 ENV CHROME_BIN=/usr/bin/chromium-browser ENV CHROMEDRIVER_BIN=/usr/bin/chromedriver WORKDIR /app COPY package*.json ./ RUN npm ci COPY . . CMD ["npm", "start"]
2. Selenium Manager自动下载的Chrome与Alpine兼容性问题
Selenium Manager下载的Chrome针对标准Linux发行版构建,与Alpine的musl libc不兼容,导致启动失败。
解决方法:
在ChromeOptions中指定系统安装的Chrome路径,避免使用自动下载的版本:
const chromeOptions = new chrome.Options(); chromeOptions.setChromeBinaryPath('/usr/bin/chromium-browser'); // 指定Alpine自带的Chromium路径
3. 缺少--disable-dev-shm-usage参数
Docker容器的/dev/shm空间有限,Chrome默认依赖该空间,空间不足会导致崩溃。
解决方法:
在ChromeOptions中添加该参数:
chromeOptions.addArguments('--disable-dev-shm-usage')
4. 以非root用户运行(可选但推荐)
Chrome在root用户下运行存在安全限制,即使添加了--no-sandbox,切换到非root用户能避免潜在问题。
解决方法:
修改Dockerfile添加非root用户:
RUN addgroup -S appgroup && adduser -S appuser -G appgroup USER appuser
最终整合后的代码示例
修改后的Dockerfile
FROM node:20-alpine # 添加Chrome运行依赖 RUN apk add --no-cache \ chromium \ chromium-chromedriver \ nss \ freetype \ harfbuzz \ ca-certificates \ ttf-freefont # 创建非root用户 RUN addgroup -S appgroup && adduser -S appuser -G appgroup # 设置环境变量 ENV CHROME_BIN=/usr/bin/chromium-browser ENV CHROMEDRIVER_BIN=/usr/bin/chromedriver WORKDIR /app COPY package*.json ./ RUN npm ci COPY . . # 切换到非root用户 USER appuser CMD ["npm", "start"]
修改后的index.js
const {Builder, Browser} = require('selenium-webdriver'); const chrome = require('selenium-webdriver/chrome'); const userAgent = 'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/60.0.3112.50 Safari/537.36' const check = async () => { console.log('Run check') const chromeOptions = new chrome.Options(); const driver = new Builder() .forBrowser(Browser.CHROME) .setChromeOptions( chromeOptions .setChromeBinaryPath('/usr/bin/chromium-browser') // 指定系统Chromium路径 .addArguments('--ignore-ssl-errors=yes') .addArguments('--ignore-certificate-errors') .addArguments('--no-sandbox') .addArguments('--headless=new') .addArguments('--window-size=1920,1080') .addArguments(`user-agent=${userAgent}`) .addArguments('--disable-dev-shm-usage') // 解决/dev/shm空间不足问题 ) .build(); await driver.get('https://www.google.com'); console.log('loaded!'); // 关闭driver避免资源泄漏 await driver.quit(); } // 执行检查函数 check().catch(err => console.error(err));
内容的提问来源于stack exchange,提问作者Nikita
相关产品推荐
相关产品推荐

