M1芯片Mac Docker容器中Chromedriver异常退出(错误码255)求助
在M1 MacBook的Docker中运行Chrome测试时遇"chromedriver意外退出,错误代码255"的解决办法
核心问题排查
你的问题主要出在三个地方:Docker指令覆盖导致依赖服务未启动、ChromeDriver与Chromium版本不匹配、启动参数冲突/不适配arm64架构。以下是针对性的修复方案:
1. 修复Dockerfile
原Dockerfile中两个CMD指令会互相覆盖,导致Xvfb虚拟显示服务未启动;同时依赖安装可以进一步优化,确保arm64架构兼容性:
FROM python:3.10-alpine3.17 # 安装Chromium、对应驱动及虚拟显示依赖 RUN apk update && \ apk add --no-cache chromium chromium-chromedriver xvfb wget curl unzip gnupg # 设置环境变量 ENV DISPLAY=:99 ENV BROWSER=chrome # 创建工作目录并复制代码(移除重复的COPY/ADD指令) RUN mkdir -p /pytest-container COPY . /pytest-container/ WORKDIR /pytest-container/ # 安装Python依赖后清理编译包,减小镜像体积 RUN apk add --no-cache --virtual .build-deps build-base python3-dev libffi-dev && \ pip install --upgrade pip && \ pip3 install -r requirements.txt && \ rm -rf /var/cache/apk/* && \ apk del .build-deps # 用shell命令串联启动Xvfb和pytest,避免CMD覆盖 CMD ["sh", "-c", "Xvfb :99 -screen 0 1024x768x16 -nolisten tcp & sleep 2 && pytest"]
2. 修复conftest.py
原代码中用ChromeDriverManager安装的驱动与apk包的Chromium版本不匹配,同时部分参数在arm64环境下会导致崩溃:
import os import pytest from selenium import webdriver from selenium.webdriver.chrome.service import Service from selenium.webdriver.chrome.options import Options @pytest.fixture(scope="class") def setup(request): browser = os.getenv('BROWSER', 'chrome') # 直接使用apk安装的ChromeDriver,保证版本匹配 service = Service(executable_path="/usr/bin/chromedriver") options = Options() # 适配Docker与arm64的启动参数 options.add_argument('--no-sandbox') options.add_argument('--disable-blink-features=AutomationControlled') options.add_argument("--headless=new") # 新版Headless更稳定 options.add_experimental_option('useAutomationExtension', False) options.add_experimental_option("excludeSwitches", ["enable-automation"]) options.add_argument("--disable-extensions") options.add_argument('--disable-dev-shm-usage') options.add_argument("window-size=1024,768") options.add_argument("--log-level=3") options.add_argument("--silent") options.add_argument("--crash-dumps-dir=/tmp") # 指定系统安装的Chromium路径 options.binary_location = "/usr/lib/chromium/chrome" if browser == "chrome": driver = webdriver.Chrome(service=service, options=options) elif browser == "firefox": from selenium.webdriver.firefox.service import Service as FirefoxService from webdriver_manager.firefox import GeckoDriverManager driver = webdriver.Firefox(service=FirefoxService(GeckoDriverManager().install())) elif browser == "edge": from selenium.webdriver.edge.service import Service as EdgeService from webdriver_manager.microsoft import EdgeChromiumDriverManager driver = webdriver.Edge(service=EdgeService(EdgeChromiumDriverManager().install())) else: driver = webdriver.Chrome(service=service, options=options) driver.get("https://www.example.com") # 补充协议头,避免访问失败 request.cls.driver = driver yield driver.quit() # 彻底关闭浏览器进程,避免残留 def pytest_addoption(parser): parser.addoption("--browser", action="store", default=os.environ.get('BROWSER', 'chrome'), help="指定测试使用的浏览器(chrome, firefox, edge)") @pytest.fixture(scope="class", autouse=True) def browser(request): return request.config.getoption("--browser")
3. 验证步骤
- 重新构建镜像:
docker build -t pytest-chrome . - 运行容器:
docker run --rm pytest-chrome
如果仍有问题,可以添加日志排查:
- 在Dockerfile中加入
ENV CHROME_LOG_FILE=/tmp/chrome.log - 在conftest的options中添加
options.add_argument("--log-path=/tmp/chrome.log") - 运行容器后查看日志:
docker exec <容器ID> cat /tmp/chrome.log
内容的提问来源于stack exchange,提问作者Anisha Singh
相关产品推荐
相关产品推荐

