Docker容器中运行Selenium脚本时进程意外崩溃求助
问题背景
我是Docker和Linux新手,正在开发自动化网页机器人,计划容器化后部署到AWS Fargate。当前使用AI生成并调试过的Dockerfile运行Selenium脚本时,容器立即崩溃,报错selenium.common.exceptions.WebDriverException: Message: Process unexpectedly closed with status 0,尝试多个AI工具调试未解决。
相关代码与配置
Python Selenium脚本
from selenium import webdriver from selenium.webdriver.firefox.service import Service from selenium.webdriver.firefox.options import Options from selenium.webdriver.common.by import By # Docker path's profilePath = "/root/.mozilla/firefox/4jqf9xwi.default-release" firefoxPath = "/usr/bin/firefox" firefoxDriver = "/usr/local/bin/geckodriver" upvoteButtonPath = "/html/body/div[2]/div/div[2]/div[2]/main/div/ul/li/article/div[2]/div[2]/div[2]/div[1]/div/div[1]/button" options = Options() options.profile = profilePath options.binary_location = firefoxPath options.add_argument("--headless") options.add_argument("--disable-gpu") # Force software rendering options.add_argument("--no-sandbox") # Avoid sandboxing issues in Docker options.add_argument("--disable-dev-shm-usage") # Prevent crashes due to shared memory service = Service(firefoxDriver) driver = webdriver.Firefox(service=service, options=options) driver.get("https://yad2.co.il/my-ads") driver.implicitly_wait(5) upVoteButton = driver.find_element(By.XPATH, upvoteButtonPath) upVoteButton.click() input("press Enter to close") driver.quit()
Dockerfile
# Use an official Python runtime as a base image FROM python:3.9-slim # Set up environment variables for non-interactive installs ENV DEBIAN_FRONTEND=noninteractive # Install necessary dependencies in a single RUN command to reduce layers RUN apt-get update && apt-get install -y \ wget \ curl \ unzip \ ca-certificates \ libx11-dev \ libxcomposite-dev \ libxrandr-dev \ libgdk-pixbuf2.0-0 \ libgtk-3-0 \ libnss3 \ libasound2 \ fonts-liberation \ libappindicator3-1 \ libxss1 \ libxtst6 \ xdg-utils \ firefox-esr \ && apt-get clean && rm -rf /var/lib/apt/lists/* # Clean up apt cache to reduce size # Install GeckoDriver manually RUN GECKO_VERSION=v0.36.0 && \ wget https://github.com/mozilla/geckodriver/releases/download/$GECKO_VERSION/geckodriver-$GECKO_VERSION-linux64.tar.gz && \ tar -xvzf geckodriver-$GECKO_VERSION-linux64.tar.gz && \ mv geckodriver /usr/local/bin/ && \ rm geckodriver-$GECKO_VERSION-linux64.tar.gz RUN apt-get update && apt-get install -y \ libgtk-3-0 \ libx11-xcb1 \ libdbus-glib-1-2 \ libxt6 \ libpci3 \ xvfb # Install Python dependencies RUN pip install --no-cache-dir selenium # Copy Firefox profile into the container COPY 4jqf9xwi.default-release /root/.mozilla/firefox/4jqf9xwi.default-release/ # Set up the working directory WORKDIR /app # Copy the Selenium script to the container COPY script.py /app/ # Default command to run the script CMD ["python", "script.py"]
报错信息
2025-03-04 11:34:22 Traceback (most recent call last): 2025-03-04 11:34:22 File "/app/script.py", line 29, in 2025-03-04 11:34:22 driver = webdriver.Firefox(service=service, options=options) 2025-03-04 11:34:22 File "/usr/local/lib/python3.9/site-packages/selenium/webdriver/firefox/webdriver.py", line 71, in __init__ 2025-03-04 11:34:22 super().__init__(command_executor=executor, options=options) 2025-03-04 11:34:22 File "/usr/local/lib/python3.9/site-packages/selenium/webdriver/remote/webdriver.py", line 250, in __init__ 2025-03-04 11:34:22 self.start_session(capabilities) 2025-03-04 11:34:22 File "/usr/local/lib/python3.9/site-packages/selenium/webdriver/remote/webdriver.py", line 342, in start_session 2025-03-04 11:34:22 response = self.execute(Command.NEW_SESSION, caps)["value"] 2025-03-04 11:34:22 File "/usr/local/lib/python3.9/site-packages/selenium/webdriver/remote/webdriver.py", line 429, in execute 2025-03-04 11:34:22 self.error_handler.check_response(response) 2025-03-04 11:34:22 File "/usr/local/lib/python3.9/site-packages/selenium/webdriver/remote/errorhandler.py", line 232, in check_response 2025-03-04 11:34:22 raise exception_class(message, screen, stacktrace) 2025-03-04 11:34:22 selenium.common.exceptions.WebDriverException: Message: Process unexpectedly closed with status 0
排查与修复步骤
1. 修正Firefox二进制文件路径
Dockerfile中安装的是firefox-esr,其默认路径为/usr/bin/firefox-esr,但Python脚本中指定的firefoxPath是/usr/bin/firefox,导致Selenium无法找到Firefox可执行文件,直接退出进程。
修改脚本中的路径:
firefoxPath = "/usr/bin/firefox-esr"
2. 修复自定义Firefox Profile权限
复制到容器中的Profile目录权限可能与容器内的root用户不匹配,导致Firefox无法读取配置文件。
在Dockerfile中添加权限修改命令(放在COPY Profile之后):
# Copy Firefox profile into the container COPY 4jqf9xwi.default-release /root/.mozilla/firefox/4jqf9xwi.default-release/ # Fix profile permissions RUN chown -R root:root /root/.mozilla/firefox/4jqf9xwi.default-release/
3. 更新Firefox Headless模式参数
旧的--headless参数在新版Firefox中已被废弃,推荐使用--headless=new以获得更好的兼容性和稳定性。
修改脚本中的参数:
options.add_argument("--headless=new")
4. 确保GeckoDriver与Firefox版本兼容
GeckoDriver与Firefox版本必须严格对应,否则会出现启动失败问题:
- 查看容器中Firefox ESR版本:执行
apt-cache show firefox-esr | grep Version - 对照版本对应关系调整GeckoDriver版本(例如Firefox 115 ESR对应GeckoDriver 0.33.0,Firefox 120+对应0.36.0)
如果当前GeckoDriver版本不匹配,修改Dockerfile中的GECKO_VERSION:
RUN GECKO_VERSION=v0.33.0 && \ wget https://github.com/mozilla/geckodriver/releases/download/$GECKO_VERSION/geckodriver-$GECKO_VERSION-linux64.tar.gz && \ tar -xvzf geckodriver-$GECKO_VERSION-linux64.tar.gz && \ mv geckodriver /usr/local/bin/ && \ rm geckodriver-$GECKO_VERSION-linux64.tar.gz
5. 使用XVFB虚拟显示(可选)
即使在Headless模式下,部分环境仍需要虚拟显示支持,修改Dockerfile的CMD命令用xvfb-run包裹:
CMD ["xvfb-run", "--auto-servernum", "python", "script.py"]
6. 优化Dockerfile依赖安装
合并重复的依赖安装命令,减少镜像层:
将第二个RUN命令中的依赖合并到第一个RUN中,删除重复的libgtk-3-0安装:
RUN apt-get update && apt-get install -y \ wget \ curl \ unzip \ ca-certificates \ libx11-dev \ libxcomposite-dev \ libxrandr-dev \ libgdk-pixbuf2.0-0 \ libgtk-3-0 \ libnss3 \ libasound2 \ fonts-liberation \ libappindicator3-1 \ libxss1 \ libxtst6 \ xdg-utils \ firefox-esr \ libx11-xcb1 \ libdbus-glib-1-2 \ libxt6 \ libpci3 \ xvfb \ && apt-get clean && rm -rf /var/lib/apt/lists/*
验证修复
重新构建镜像并运行容器:
docker build -t selenium-firefox . docker run --rm selenium-firefox
如果仍有问题,可添加日志输出调试:在Python脚本中添加Firefox日志配置,查看启动细节:
options.log.level = "trace" service.log_path = "/tmp/geckodriver.log"
内容的提问来源于stack exchange,提问作者ShaiGross

