Docker 部署 Node.js + Playwright 项目,实现浏览器截图、打印和下载
- 一、项目目录结构
- 二、Dockerfile
-
- [2.1 完整 Dockerfile 内容](#2.1 完整 Dockerfile 内容)
- [2.2 Dockerfile 详解](#2.2 Dockerfile 详解)
- [三、docker-compose.yml 详解](#三、docker-compose.yml 详解)
- [四、自动化部署脚本 deploy-node.sh](#四、自动化部署脚本 deploy-node.sh)
- [五、Playwright 浏览器截图/打印示例](#五、Playwright 浏览器截图/打印示例)
- 六、优化建议
- 七、总结
在现代前端/自动化测试项目中,Playwright 常用于浏览器自动化操作,如截图、打印和下载 PDF。
本文详细介绍如何在 Linux 环境下使用 Docker 部署 Node.js + Playwright 项目,并对 Dockerfile、docker-compose 和自动化部署脚本逐行解析。

一、项目目录结构
假设项目目录为 /opt/test/front-node/,结构如下:
/opt/test/front-node/
├── node/
│ ├── src/ # Node.js 源码
│ ├── package.json
│ ├── pnpm-lock.yaml
│ ├── assets/ # 静态资源
│ └── test.js # Playwright 测试脚本
├── Dockerfile # Docker 镜像构建文件
├── docker-compose.yml # Docker Compose 服务定义
└── deploy-node.sh # 自动化部署脚本
说明:
node/文件夹包含完整 Node.js 应用- 其他文件用于 Docker 构建和部署
二、Dockerfile
2.1 完整 Dockerfile 内容
下面是完整的 Dockerfile:
dockerfile
# 基于官方 Node.js 镜像
FROM node:20-bullseye
LABEL authors="test"
# 设置非交互模式
ENV DEBIAN_FRONTEND=noninteractive
# 使用清华源 + 安装必要依赖(Playwright 运行时)
RUN sed -i 's|http://deb.debian.org/debian|https://mirrors.tuna.tsinghua.edu.cn/debian|g' /etc/apt/sources.list && \
apt-get update && \
apt-get install -y --no-install-recommends \
libnss3 libnspr4 libatk1.0-0 libatk-bridge2.0-0 libcups2 \
libdrm2 libxkbcommon0 libatspi2.0-0 libxcomposite1 libxdamage1 \
libxfixes3 libxrandr2 libgbm1 libasound2 curl ca-certificates git \
&& rm -rf /var/lib/apt/lists/*
# 设置工作目录
WORKDIR /usr/src/app
# 先仅复制依赖声明文件,加快构建缓存
COPY node/package*.json ./
# 使用国内 npm 源
RUN npm config set registry https://registry.npmmirror.com/
# 切换目录安装依赖
WORKDIR /usr/src/app/node
RUN npm install --omit=dev --loglevel=error
# 复制完整项目代码(最后执行,避免频繁失效缓存)
COPY node ./
# 设置环境变量以通过 npm 安装浏览器
ENV PLAYWRIGHT_SKIP_BROWSER_DOWNLOAD=1
# 先安装依赖包
RUN npm install --omit=dev
# 再手动用 npm 装 chromium
RUN npx playwright install chromium --with-deps --force
# 暴露端口
EXPOSE 3001
# 启动命令
CMD ["npm", "run", "start"]
2.2 Dockerfile 详解
dockerfile
# 基于官方 Node.js 镜像
FROM node:20-bullseye
LABEL authors="test"
# 设置非交互模式,避免 apt-get 安装弹出交互界面
ENV DEBIAN_FRONTEND=noninteractive
# 使用清华源加速 Debian 包下载,同时安装 Playwright 运行依赖
RUN sed -i 's|http://deb.debian.org/debian|https://mirrors.tuna.tsinghua.edu.cn/debian|g' /etc/apt/sources.list && \
apt-get update && \
apt-get install -y --no-install-recommends \
libnss3 libnspr4 libatk1.0-0 libatk-bridge2.0-0 libcups2 \
libdrm2 libxkbcommon0 libatspi2.0-0 libxcomposite1 libxdamage1 \
libxfixes3 libxrandr2 libgbm1 libasound2 curl ca-certificates git \
&& rm -rf /var/lib/apt/lists/*
🔹 解析
-
基础镜像 :
node:20-bullseye-
Node 20 官方 Debian 版本,体积适中,兼容 Playwright
-
选择 Debian 而不是 Alpine,是因为 Playwright 对 Chromium 依赖较多,Alpine 缺少很多库容易报错
-
-
非交互模式 :
ENV DEBIAN_FRONTEND=noninteractive- 避免
apt-get install过程中弹出交互提示导致构建卡住
- 避免
-
清华源加速 :
sed -i 's|http://deb.debian.org/debian|https://mirrors.tuna.tsinghua.edu.cn/debian|g'- 国内访问 Debian 官方源慢,替换成清华镜像,加速依赖安装
-
安装 Chromium 运行依赖
-
Playwright 需要一些系统库,如
libnss3、libatk1.0-0、libcups2等 -
--no-install-recommends避免安装不必要的额外软件,减小镜像体积
-
dockerfile
# 设置工作目录
WORKDIR /usr/src/app
# 先复制依赖声明文件,加快 Docker 缓存
COPY node/package*.json ./
# 使用国内 npm 镜像
RUN npm config set registry https://registry.npmmirror.com/
🔹 解析
-
WORKDIR
- 设置镜像工作目录,所有后续操作都在
/usr/src/app进行
- 设置镜像工作目录,所有后续操作都在
-
COPY package.json*
-
先只复制依赖文件,不复制源码
-
利用 Docker 缓存层,如果
package.json未修改,npm install不会重复执行
-
-
npm 镜像加速
-
国内访问官方 npm registry 速度慢
-
使用
registry.npmmirror.com可以大幅加快依赖安装
-
dockerfile
# 切换目录安装依赖
WORKDIR /usr/src/app/node
RUN npm install --omit=dev --loglevel=error
🔹 解析
-
WORKDIR 切换到 node:保证依赖安装在项目源代码目录下
-
npm install --omit=dev:生产环境只安装必要依赖,不安装 devDependencies
-
--loglevel=error:减少构建日志输出
dockerfile
# 复制完整项目代码
COPY node ./
# 设置 Playwright 环境变量,跳过浏览器自动下载
ENV PLAYWRIGHT_SKIP_BROWSER_DOWNLOAD=1
# 再安装依赖
RUN npm install --omit=dev
# 手动安装 Chromium
RUN npx playwright install chromium --with-deps --force
🔹 解析
-
复制完整项目
- 先安装依赖,再复制源码,可以利用 Docker 缓存,加快 rebuild
-
跳过自动下载浏览器
- 避免
npm install playwright时重复下载 Chromium,减少网络依赖
- 避免
-
手动安装 Chromium
-
--with-deps安装 Playwright 运行所需的所有系统依赖 -
--force确保每次安装都是最新版本
-
dockerfile
# 暴露端口
EXPOSE 3001
# 启动命令
CMD ["npm", "run", "start"]
🔹 解析
-
EXPOSE 3001:容器对外暴露端口
-
CMD:容器启动时执行的命令,运行 Node.js 服务
三、docker-compose.yml 详解
yaml
version: "3.9"
services:
front-node:
build:
context: .
dockerfile: Dockerfile
image: test-node:latest # <-- 指定镜像名称
container_name: test-node
restart: always
ports:
- "3001:3001"
environment:
- NODE_ENV=production
working_dir: /usr/src/app
command: ["npm", "run", "start"]
volumes:
# 映射整个 node 项目文件夹
- /opt/test/front-node/node:/usr/src/app
# 防止 node_modules 被宿主机空目录覆盖
- /usr/src/app/node_modules
🔹 解析
-
services.front-node
- 定义 Node.js 服务
-
build.context / dockerfile
- 指定 Dockerfile 和构建上下文
-
image / container_name
- 镜像与容器命名,方便管理
-
restart: always
- 容器异常退出自动重启
-
ports
- 宿主机端口映射到容器端口
-
volumes
-
映射宿主机代码目录,方便开发调试
-
单独挂载
node_modules防止空目录覆盖
-
四、自动化部署脚本 deploy-node.sh
bash
#!/bin/bash
# 工作目录
WORKDIR="/opt/test/front-node"
# 容器和镜像名称
CONTAINER_NAME="test-node"
IMAGE_NAME="test-node:latest"
# 切换到工作目录
cd "$WORKDIR" || { echo "工作目录不存在: $WORKDIR"; exit 1; }
echo "=== 检查并停止容器 ${CONTAINER_NAME} ==="
if docker ps -a --format '{{.Names}}' | grep -w "${CONTAINER_NAME}" > /dev/null; then
docker stop "${CONTAINER_NAME}"
docker rm "${CONTAINER_NAME}"
echo "容器 ${CONTAINER_NAME} 已停止并删除"
else
echo "容器 ${CONTAINER_NAME} 不存在"
fi
echo "=== 删除镜像 ${IMAGE_NAME} ==="
if docker images --format '{{.Repository}}:{{.Tag}}' | grep -w "${IMAGE_NAME}" > /dev/null; then
docker rmi "${IMAGE_NAME}" -f
echo "镜像 ${IMAGE_NAME} 已删除"
else
echo "镜像 ${IMAGE_NAME} 不存在"
fi
echo "=== 构建镜像并启动容器 ==="
docker compose build
docker compose up -d
echo "=== 完成 ==="
🔹 解析
-
自动停止旧容器:避免端口冲突
-
删除旧镜像:保证构建最新版本
-
docker compose build + up:构建镜像并启动容器
-
一键部署:Linux 下快速上线
五、Playwright 浏览器截图/打印示例
javascript
const { chromium } = require('playwright');
(async () => {
const browser = await chromium.launch();
const page = await browser.newPage();
await page.goto('https://example.com');
// 截图
await page.screenshot({ path: 'example.png' });
// 打印 PDF
await page.pdf({ path: 'example.pdf', format: 'A4' });
await browser.close();
})();
🔹 解析
-
chromium.launch():启动浏览器实例
-
page.goto():访问页面
-
page.screenshot() / page.pdf():实现截图和打印功能
-
支持自动化生成报告、文件下载等操作
六、优化建议
-
国内加速源
-
Debian 清华源 + npm 镜像
-
显著提升构建速度
-
-
缓存依赖
-
先复制
package*.json再安装依赖 -
再复制源码,减少重复构建
-
-
非 root 用户运行
- 提升安全性
-
分阶段构建(可选)
-
构建阶段安装 Playwright
-
生产阶段只复制 Node + 依赖
-
镜像更小,启动更快
-
七、总结
在 Linux 使用 Docker 部署 Node.js + Playwright 项目 的方案,涵盖:
-
Dockerfile 构建 Playwright 所需环境
-
docker-compose 服务配置
-
自动化部署脚本
-
浏览器截图与打印示例
通过上述方法,可以快速在国内 Linux 环境部署 Playwright 项目,并支持截图、打印和下载等自动化操作。