Docker环境下Selenium Chrome Driver配置失败求助
解决Docker中Selenium+Chrome Driver的PermissionError: '/nonexistent'问题
这个PermissionError: [Errno 13] Permission denied: '/nonexistent'错误,本质是Chrome在容器内尝试创建默认用户数据目录失败——当Chrome无法找到指定的用户数据目录时,会 fallback 到/nonexistent,但当前运行用户没有该目录的读写权限(通常是用非root用户运行,但未提前配置合法的目录)。
一、修正Dockerfile:确保权限与依赖正确
不要零散手动安装Chrome/Driver,推荐用官方维护的安装脚本,同时创建有读写权限的用户数据目录,并指定运行用户:
# 基于Python官方镜像 FROM python:3.10-slim # 安装Chrome依赖与基础工具 RUN apt-get update && apt-get install -y \ wget \ gnupg \ unzip \ fonts-liberation \ libasound2 \ libatk-bridge2.0-0 \ libatk1.0-0 \ libcups2 \ libdbus-1-3 \ libdrm2 \ libgbm1 \ libnspr4 \ libnss3 \ libx11-xcb1 \ libxcb-dri3-0 \ libxcomposite1 \ libxdamage1 \ libxrandr2 \ xdg-utils \ libxss1 \ libxtst6 \ && rm -rf /var/lib/apt/lists/* # 安装Chrome浏览器 RUN wget -q -O - https://dl.google.com/linux/linux_signing_key.pub | apt-key add - \ && echo "deb [arch=amd64] http://dl.google.com/linux/chrome/deb/ stable main" >> /etc/apt/sources.list.d/google.list \ && apt-get update && apt-get install -y google-chrome-stable \ && rm -rf /var/lib/apt/lists/* # 安装对应版本的ChromeDriver RUN CHROME_VERSION=$(google-chrome --version | grep -oP '\d+\.\d+\.\d+\.\d+') \ && wget -q https://chromedriver.storage.googleapis.com/chrome-for-testing/latest/linux64/chromedriver-linux64.zip \ && unzip chromedriver-linux64.zip \ && mv chromedriver-linux64/chromedriver /usr/local/bin/ \ && chmod +x /usr/local/bin/chromedriver \ && rm -rf chromedriver-linux64.zip chromedriver-linux64 # 创建Chrome用户数据目录并设置权限 RUN mkdir -p /tmp/chrome-user-data \ && chmod -R 777 /tmp/chrome-user-data # 创建非root用户(推荐,避免权限过大) RUN useradd -m selenium-user \ && chown -R selenium-user:selenium-user /tmp/chrome-user-data # 切换到非root用户 USER selenium-user # 安装Python依赖 COPY requirements.txt . RUN pip install --no-cache-dir -r requirements.txt # 复制业务代码 COPY app.py . CMD ["python", "app.py"]
二、调整Python代码:指定合法的用户数据目录与Chrome启动参数
必须给Chrome指定有读写权限的用户数据目录,同时添加Docker运行必需的参数:
from selenium import webdriver from selenium.webdriver.chrome.options import Options def init_driver(): chrome_options = Options() # Docker运行Chrome必需的核心参数 chrome_options.add_argument("--headless=new") chrome_options.add_argument("--no-sandbox") chrome_options.add_argument("--disable-dev-shm-usage") # 指定用户数据目录到/tmp下的合法路径 chrome_options.add_argument(f"--user-data-dir=/tmp/chrome-user-data") # 可选:禁用GPU、固定窗口大小 chrome_options.add_argument("--disable-gpu") chrome_options.add_argument("--window-size=1920,1080") # 初始化Driver(系统路径已配置正确,无需额外指定executable_path) driver = webdriver.Chrome(options=chrome_options) return driver if __name__ == "__main__": driver = init_driver() try: driver.get("https://www.google.com") print("页面标题:", driver.title) finally: driver.quit()
三、修正compose.yaml:确保目录权限(如果使用)
如果用Docker Compose,无需额外挂载目录(Dockerfile已创建合法目录);若要挂载宿主机目录,需确保宿主机目录权限为777或对应用户:
version: '3.8' services: selenium-chrome: build: . # 可选挂载宿主机目录,需提前执行:mkdir chrome-data && chmod 777 chrome-data # volumes: # - ./chrome-data:/tmp/chrome-user-data environment: - PYTHONUNBUFFERED=1
常见问题排查
- 版本不匹配:必须保证Chrome与ChromeDriver版本完全一致,上述Dockerfile会自动安装对应版本的Driver,避免版本冲突。
- 非root用户权限不足:若自定义用户,必须确保该用户对
--user-data-dir指定的目录有读写权限,Dockerfile中的chown命令已处理此问题。 - 缺失禁用沙箱参数:Docker容器内没有完整的Linux命名空间,必须添加
--no-sandbox参数,否则Chrome无法启动。
内容的提问来源于stack exchange,提问作者anderson
相关产品推荐
相关产品推荐

