Docker 部署 Node.js + Playwright 项目,实现浏览器截图、打印和下载

Docker 部署 Node.js + 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/*

🔹 解析

  1. 基础镜像node:20-bullseye

    • Node 20 官方 Debian 版本,体积适中,兼容 Playwright

    • 选择 Debian 而不是 Alpine,是因为 Playwright 对 Chromium 依赖较多,Alpine 缺少很多库容易报错

  2. 非交互模式ENV DEBIAN_FRONTEND=noninteractive

    • 避免 apt-get install 过程中弹出交互提示导致构建卡住
  3. 清华源加速sed -i 's|http://deb.debian.org/debian|https://mirrors.tuna.tsinghua.edu.cn/debian|g'

    • 国内访问 Debian 官方源慢,替换成清华镜像,加速依赖安装
  4. 安装 Chromium 运行依赖

    • Playwright 需要一些系统库,如 libnss3libatk1.0-0libcups2

    • --no-install-recommends 避免安装不必要的额外软件,减小镜像体积


dockerfile 复制代码
# 设置工作目录
WORKDIR /usr/src/app

# 先复制依赖声明文件,加快 Docker 缓存
COPY node/package*.json ./

# 使用国内 npm 镜像
RUN npm config set registry https://registry.npmmirror.com/

🔹 解析

  1. WORKDIR

    • 设置镜像工作目录,所有后续操作都在 /usr/src/app 进行
  2. COPY package.json*

    • 先只复制依赖文件,不复制源码

    • 利用 Docker 缓存层,如果 package.json 未修改,npm install 不会重复执行

  3. 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

🔹 解析

  1. 复制完整项目

    • 先安装依赖,再复制源码,可以利用 Docker 缓存,加快 rebuild
  2. 跳过自动下载浏览器

    • 避免 npm install playwright 时重复下载 Chromium,减少网络依赖
  3. 手动安装 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

🔹 解析

  1. services.front-node

    • 定义 Node.js 服务
  2. build.context / dockerfile

    • 指定 Dockerfile 和构建上下文
  3. image / container_name

    • 镜像与容器命名,方便管理
  4. restart: always

    • 容器异常退出自动重启
  5. ports

    • 宿主机端口映射到容器端口
  6. 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():实现截图和打印功能

  • 支持自动化生成报告、文件下载等操作


六、优化建议

  1. 国内加速源

    • Debian 清华源 + npm 镜像

    • 显著提升构建速度

  2. 缓存依赖

    • 先复制 package*.json 再安装依赖

    • 再复制源码,减少重复构建

  3. 非 root 用户运行

    • 提升安全性
  4. 分阶段构建(可选)

    • 构建阶段安装 Playwright

    • 生产阶段只复制 Node + 依赖

    • 镜像更小,启动更快


七、总结

在 Linux 使用 Docker 部署 Node.js + Playwright 项目 的方案,涵盖:

  • Dockerfile 构建 Playwright 所需环境

  • docker-compose 服务配置

  • 自动化部署脚本

  • 浏览器截图与打印示例

通过上述方法,可以快速在国内 Linux 环境部署 Playwright 项目,并支持截图、打印和下载等自动化操作。


相关推荐
2401_840192278 小时前
什么是ingress?
docker·容器·kubernetes
攀小黑10 小时前
docker 容器内nacos(若依plus打包)连接另一台内网服务器显示数据库连接失败
服务器·数据库·docker
晚风 -10 小时前
idea中Docker一键自动化部署
docker·容器·自动化
Hilaku11 小时前
前端开发,真的有必要学Docker吗?
前端·javascript·docker
前端摸鱼匠11 小时前
Vue 3 事件修饰符全解析:从 .stop 到 .passive,彻底掌握前端交互的艺术
前端·vue.js·node.js·vue·交互
小琴爱减肥11 小时前
nodejs 文件系统(fs)
node.js
Java陈序员12 小时前
代码检测器!一款专门揭露屎山代码的质量分析工具!
docker·go
岁月宁静12 小时前
图像生成接口的工程化设计与落地实践:封装豆包图像生成模型 Seedream 4.0 API
前端·人工智能·node.js