容器化中运行 Playwright并驱动 Chrome

方案一:使用 Playwright 官方镜像(推荐)

Playwright 官方团队维护了包含完整环境的 Docker 镜像,里面已经内置了 Node.js/Python 环境以及所有浏览器运行所需的依赖,是最不容易踩坑的方案。

1. 选择镜像

根据你使用的编程语言,拉取对应的官方镜像:

  • Node.js: mcr.microsoft.com/playwright:v1.61.0-noble
  • Python: mcr.microsoft.com/playwright/python:v1.60.0-noble

2. 编写代码(以 Python 为例)

在代码中,如果你想明确指定驱动 Google Chrome(而非 Playwright 默认的开源 Chromium),可以通过设置 channel="chrome" 来实现。

1
2
3
4
5
6
7
8
9
10
11
12
13
from playwright.sync_api import sync_playwright

with sync_playwright() as p:
# 使用 channel="chrome" 指定正版 Google Chrome 渠道
browser = p.chromium.launch(
headless=True,
channel="chrome",
args=["--no-sandbox", "--disable-setuid-sandbox"]
)
page = browser.new_page()
page.goto("https://example.com")
print(page.title())
browser.close()

方案二:在自定义基础镜像中安装

如果你必须基于公司现有的 Linux 基础镜像(如 ubuntudebian)进行构建,可以参考以下 Dockerfile 配置。

注意: 极度不建议使用 alpine 镜像,因为 Playwright 的浏览器二进制文件是为 glibc 编译的,在 Alpine 的 musl 环境下极难跑通。

1. 编写 Dockerfile(Python 示例)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
FROM python:3.11-slim-bookworm

WORKDIR /app

# 安装基础工具
RUN apt-get update && apt-get install -y \
wget \
gnupg \
&& rm -rf /var/lib/apt/lists/*

# 升级 pip 并安装 playwright python 包
RUN pip install --no-cache-dir --upgrade pip && \
pip install --no-cache-dir playwright

# 【核心步骤】安装指定浏览器(chrome)及其所需的全部 Linux 系统依赖
RUN playwright install --with-deps chrome

# 复制业务代码
COPY . .

CMD ["python", "main.py"]

2. 编写 Dockerfile(Node.js 示例)

1
2
3
4
5
6
7
8
9
10
11
12
13
FROM node:20-bookworm-slim

WORKDIR /app

COPY package*.json ./
RUN npm ci

# 【核心步骤】利用 npx 安装 chrome 浏览器和系统依赖
RUN npx playwright install --with-deps chrome

COPY . .

CMD ["node", "index.js"]

踩坑与优化指南

在容器内跑 Chrome,以下几点如果没配置好,程序大概率会报错或频繁崩溃:

1. 共享内存不足导致崩溃(/dev/shm

Docker 容器默认分配的共享内存通常只有 64MB,当 Chrome 打开较复杂的网页时,会因为内存耗尽而直接崩溃(报错通常为 Target closedCrash)。

  • 解决方案:在启动 Docker 容器时,必须加上 --ipc=host 参数,允许容器共享宿主机的内存。
1
docker run -it --rm --ipc=host my-playwright-app

2. Chrome 沙盒权限问题(Sandbox)

Linux 的 Chromium/Chrome 默认使用沙盒机制保障安全,但在 Docker 容器中(尤其是以 root 用户运行时),沙盒往往会因为没有内核权限而报错。

  • 临时解决(信任代码):在代码启动浏览器时,添加启动参数 args=["--no-sandbox", "--disable-setuid-sandbox"]
  • 标准解决(抓取不信任网站):Playwright 官方镜像内置了一个名为 pwuser 的非 root 用户。推荐在 Dockerfile 中切换到该用户,或者在运行容器时使用安全配置文件(seccomp)。

3. 无头模式(Headless)

在没有安装 X11 桌面环境的 Linux 容器中,必须以无头模式运行 Chrome:

1
browser = p.chromium.launch(headless=True)

如果你确实需要有头模式(Headless=False)来调试或截图,你需要在 Docker 内部部署并启动 Xvfb(虚拟帧缓冲区),利用 xvfb-run python main.py 来欺骗 Chrome 拥有显示器。