如何在.NET Docker容器中以有头模式运行Playwright?
问题:Docker容器中Playwright有头模式Firefox无法运行
我在Docker容器中使用Playwright运行有头模式的Firefox时失败,但无头模式可以正常工作。该镜像基于Ubuntu 22,以下是我的相关配置、代码及错误信息:
Dockerfile
FROM mcr.microsoft.com/dotnet/aspnet:6.0 AS base WORKDIR /app EXPOSE 80 EXPOSE 443 RUN apt-get update && apt-get install -y --no-install-recommends \ xvfb\ fonts-liberation\ libasound2\ libatk-bridge2.0-0\ libatk1.0-0\ libatspi2.0-0\ libcairo2\ libcups2\ libdbus-glib-1-2\ libdbus-1-3\ libdrm2\ libgbm1\ libglib2.0-0\ libgtk-3-0\ libnspr4\ libnss3\ libpango-1.0-0\ libx11-6\ libxcb1\ libxcomposite1\ libxdamage1\ libxext6\ libxfixes3\ libxrandr2\ libxtst6\ tzdata FROM mcr.microsoft.com/dotnet/sdk:6.0 AS build WORKDIR /src COPY ["src/Project.csproj", "src/"] RUN dotnet restore "src/Project.csproj" COPY . . WORKDIR "/src/src" RUN dotnet build "Project.csproj" -c Release -o /app/build FROM build AS publish RUN dotnet publish "Project.csproj" -c Release -o /app/publish /p:UseAppHost=false FROM base AS final WORKDIR /app COPY --from=publish /app/publish . ##ENV DISPLAY=:99 # Start Xvfb, set DISPLAY variable, and run the application ##ENTRYPOINT ["/usr/bin/xvfb-run -a $@", "dotnet", "Project.dll"] #ENTRYPOINT ["/bin/sh", "-c", "/usr/bin/xvfb-run -a $@", ""] ##CMD ["xvfb-run", "dotnet", "Project.dll"] ##CMD Xvfb :99 -ac & export DISPLAY=:99 && dotnet Project.dll ENTRYPOINT ["dotnet", "Project.dll"]
注释部分是我多次尝试但未成功的启动命令。
C#代码
using (var pw = await Playwright.CreateAsync()) { var proxyHandler = new ProxyHandler(); await using var browser = await pw.Firefox.LaunchAsync(new BrowserTypeLaunchOptions() { Headless = false }); var context = browser.NewContextAsync(new BrowserNewContextOptions() { IgnoreHTTPSErrors = true }); var page = await browser.NewPageAsync(); await page.GotoAsync("http://page"); }
错误日志
2023-09-21 21:33:31 An unhandled exception has occurred while executing the request. 2023-09-21 21:33:31 Microsoft.Playwright.PlaywrightException: 2023-09-21 21:33:31 ╔════════════════════════════════════════════════════════════════════════════════════════════════╗ 2023-09-21 21:33:31 ║ Looks like you launched a headed browser without having a XServer running. ║ 2023-09-21 21:33:31 ║ Set either 'headless: true' or use 'xvfb-run <your-playwright-app>' before running Playwright. ║ 2023-09-21 21:33:31 ║ ║ 2023-09-21 21:33:31 ║ <3 Playwright Team ║ 2023-09-21 21:33:31 ╚════════════════════════════════════════════════════════════════════════════════════════════════╝ 2023-09-21 21:33:31 =========================== logs =========================== 2023-09-21 21:33:31 <launching> /ms-playwright/firefox-1422/firefox/firefox -no-remote -wait-for-browser -foreground -profile /tmp/playwright_firefoxdev_profile-PVqbMc -juggler-pipe -silent 2023-09-21 21:33:31 <launched> pid=954 2023-09-21 21:33:31 [pid=954][err] Error: no DISPLAY environment variable specified 2023-09-21 21:33:31 [pid=954] <process did exit: exitCode=1, signal=null>
解决方案
问题核心是有头浏览器需要X服务器运行,而你的启动命令没有正确启动Xvfb并传递DISPLAY环境变量。修改Dockerfile的final阶段即可解决:
修改后的Dockerfile final阶段
FROM base AS final WORKDIR /app COPY --from=publish /app/publish . # 设置DISPLAY环境变量 ENV DISPLAY=:99 # 通过shell启动xvfb-run和应用,确保X服务器正常运行 ENTRYPOINT ["/bin/sh", "-c", "/usr/bin/xvfb-run -a dotnet Project.dll"]
关键说明
xvfb-run -a:自动启动一个Xvfb虚拟X服务器,-a参数会自动选择可用的显示编号,避免固定:99可能带来的冲突。/bin/sh -c:由于Docker的ENTRYPOINT exec格式(方括号)不支持shell语法,必须通过shell来执行xvfb-run与dotnet的组合命令,确保环境变量正确传递。
另外,你的C#代码中有个小问题:browser.NewContextAsync没有使用await,建议修复为await browser.NewContextAsync(...),避免潜在的异步问题。
内容的提问来源于stack exchange,提问作者Andy Schmitt
相关产品推荐
相关产品推荐

