在Docker Compose中以非root用户运行Selenium Chrome时遭遇DevToolsActivePort文件不存在的会话创建失败问题
在Docker Compose中以非root用户运行Selenium Chrome时遭遇DevToolsActivePort文件不存在的会话创建失败问题
看起来你遇到的是典型的非root用户在Docker容器中运行Chrome时的权限与配置不兼容问题,我来帮你分析并给出具体的解决方案:
问题根源
当你用root用户运行容器时,Chrome可以无限制访问系统默认的临时目录(比如/tmp),顺利创建DevToolsActivePort文件、用户数据目录等必要资源;但切换到非root用户ma后,Chrome没有权限访问这些默认系统目录,导致启动时无法生成DevToolsActivePort,最终触发会话创建失败的报错。
具体解决方案
我们需要从Chrome启动参数调整和Dockerfile目录权限配置两方面入手,确保非root用户能正常运行Chrome:
1. 调整Selenium Chrome启动参数
修改你的start_browser函数,添加非root用户可写的用户数据目录指定、调试端口固定等关键参数:
def start_browser(portal_config: PortalSettings) -> webdriver.Chrome: options = Options() options.add_experimental_option("useAutomationExtension", False) options.add_experimental_option("excludeSwitches", ["enable-automation"]) options.add_experimental_option("detach", True) # 核心修改:指定非root用户有权限的用户数据目录 options.add_argument("--user-data-dir=/opt/ma/.cache/selenium/chrome-profile") # 固定远程调试端口,避免自动分配时的权限问题 options.add_argument("--remote-debugging-port=9222") # 推荐使用Chrome 112+的新无头模式,兼容性更好 options.add_argument("--headless=new") options.add_argument("--disable-dev-shm-usage") options.add_argument("--disable-extensions") options.add_argument("--disable-crash-reporter") options.add_argument("--disable-infobars") options.add_argument("--disable-logging") options.add_argument("--disable-background-timer-throttling") options.add_argument("--disable-backgrounding-occluded-windows") options.add_argument("--disable-renderer-backgrounding") options.add_argument("--no-sandbox") options.add_argument("--disable-gpu") options.add_argument("--start-maximized") options.add_argument('log-level=3') options.add_experimental_option('excludeSwitches', ['enable-logging']) # 显式指定Chrome二进制文件路径,避免查找错误 options.binary_location = "/usr/bin/google-chrome-stable" browser = webdriver.Chrome(options=options) browser.maximize_window() browser.get('https://www.portal.com/login') login(browser, portal_config) return browser
2. 完善Dockerfile的目录权限配置
在Dockerfile中提前创建Chrome用户数据目录,并确保ma用户拥有读写权限:
# 原有的创建.cache目录的命令替换为: RUN mkdir -p /opt/$USER/.cache/selenium /opt/$USER/.cache/selenium/chrome-profile \ && chown -R $USER:$USER /opt/$USER/.cache # 新增:安装与Chrome版本匹配的ChromeDriver(避免自动下载版本不兼容) RUN CHROME_VERSION=$(google-chrome-stable --version | grep -oP '\d+\.\d+\.\d+\.\d+') \ && wget -O /tmp/chromedriver.zip https://storage.googleapis.com/chrome-for-testing-public/$CHROME_VERSION/linux64/chromedriver-linux64.zip \ && unzip /tmp/chromedriver.zip -d /tmp \ && mv /tmp/chromedriver-linux64/chromedriver /usr/local/bin/ \ && chmod +x /usr/local/bin/chromedriver \ && rm -rf /tmp/chromedriver.zip /tmp/chromedriver-linux64
3. 额外注意事项
- 确保
poetry install中已经包含了最新版本的selenium库(推荐4.10+),旧版本对新Chrome的支持可能有问题; - 如果你使用的是较旧的Chrome版本,需要将
--headless=new改回--headless,但还是建议升级Chrome到稳定版。
为什么这些修改能解决问题?
- 指定用户数据目录:让Chrome将所有运行时数据(包括DevToolsActivePort)写入
ma用户有权限的/opt/ma/.cache/selenium/chrome-profile目录,避免了默认/tmp目录的权限限制; - 固定调试端口:避免Chrome自动分配端口时因权限不足无法绑定的问题;
- 匹配ChromeDriver版本:手动安装与容器内Chrome完全匹配的ChromeDriver,消除版本不兼容导致的会话创建失败;
- 新无头模式:
--headless=new比旧的无头模式更接近真实Chrome的运行逻辑,在非root环境下兼容性更好。
备注:内容来源于stack exchange,提问作者Dima
相关产品推荐
相关产品推荐

