Docker部署Puppeteer应用在Windows正常,Mac M1芯片运行卡顿
Puppeteer PDF生成应用在M1 Mac Docker环境下的卡顿与构建失败问题
问题现象
- 应用在Windows Docker环境运行正常,调用
http://localhost:5007/sign接口可成功生成PDF - 在Apple M1 Pro(Sonoma 14.2.1系统)Mac上部署后,执行Puppeteer相关逻辑时出现卡顿
- 运行容器时触发平台不匹配警告:
WARNING: The requested image's platform (linux/amd64) does not match the detected host platform (linux/arm64/v8) and no specific platform was requested,容器虽能启动但功能异常 - 尝试使用
docker build --platform linux/arm64/v8 -t puppetcc .构建镜像失败
环境信息
- Docker版本:25.0.3
- 已安装并启用Rosetta 2
核心原因
- 架构硬编码导致构建失败:原Dockerfile指定了
amd64架构的Chrome源和x86版本的dumb-init,无法适配arm64架构 - Rosetta模拟性能损耗:amd64镜像在arm64机器上通过Rosetta运行时,Puppeteer调用Chrome的性能大幅下降,引发卡顿
解决方案
1. 修改Dockerfile适配arm64架构
调整Chrome安装源、dumb-init下载地址,移除架构硬编码:
FROM node:20.12.2-bullseye As base # 安装Chrome依赖,适配arm64架构 RUN apt-get update \ && apt-get install -y wget gnupg \ && wget -q -O - https://dl-ssl.google.com/linux/linux_signing_key.pub | apt-key add - \ # 移除arch=amd64限制,让系统自动匹配架构 && sh -c 'echo "deb http://dl.google.com/linux/chrome/deb/ stable main" >> /etc/apt/sources.list.d/google.list' \ && apt-get update \ && apt-get install -y google-chrome-stable fonts-ipafont-gothic fonts-wqy-zenhei fonts-thai-tlwg fonts-kacst fonts-freefont-ttf libxss1 \ --no-install-recommends \ && rm -rf /var/lib/apt/lists/* # 下载适配arm64的dumb-init ADD https://github.com/Yelp/dumb-init/releases/download/v1.2.2/dumb-init_1.2.2_aarch64 /usr/local/bin/dumb-init RUN chmod +x /usr/local/bin/dumb-init ENTRYPOINT ["dumb-init", "--"] WORKDIR /app COPY package*.json /app RUN npm install COPY . /app EXPOSE 5007 CMD ["npm", "run", "st"]
2. 优化Puppeteer启动配置
在index.js中指定系统Chrome路径,并添加内存优化参数:
const express = require('express'); const app = express(); const puppeteer = require('puppeteer'); const html = `<!DOCTYPE html><html lang="en"> <head> <title></title> <style type="text/css"> .kw-offer-letter-body { text-align: justify; color: #000; background: #fff; font-family: 'Aeonik', 'Open Sans', sans-serif; font-size: 45px; line-height: 24px; } </style> </head> <body class="kw-offer-letter-body"> hello this is a pdf file.. </body></html>` async function generatePdf3(html) { try { const browser = await puppeteer.launch({ headless: 'new', args: ['--no-sandbox', '--disable-setuid-sandbox', '--disable-dev-shm-usage'], // 指定系统安装的Chrome路径,适配arm64 executablePath: '/usr/bin/google-chrome-stable' }); const page = await browser.newPage(); await page.setContent(html); const data = await page.pdf({ path: 'example5.pdf', format: 'A4', margin: { left: '2cm', top: '2cm', right: '2cm', bottom: '2cm' } }); await browser.close(); return {status:200, data: "Passed"}; // 修复原代码拼写错误:staus→status } catch (error) { return error; } } app.get('/sign', (req, res, next) => { generatePdf3(html).then(val=>{ res.status(200).send(val); }) }); app.listen(5007, () => { console.log('server running at 5007'); })
3. 构建并运行arm64镜像
执行以下命令:
# 构建arm64架构镜像 docker build --platform linux/arm64/v8 -t puppetcc . # 运行容器 docker run -d --rm -p 5007:5007 --name puppetcd puppetcc
关键说明
- 移除Chrome源中的
[arch=amd64]限制,让apt自动匹配当前架构下载对应版本的Chrome - 替换dumb-init为arm64版本(
aarch64后缀) - 指定Puppeteer使用系统安装的Chrome,避免其自动下载amd64版本的浏览器
- 添加
--disable-dev-shm-usage参数,解决容器内共享内存不足的问题
内容的提问来源于stack exchange,提问作者Shubham Shaw
相关产品推荐
相关产品推荐

