问题描述

最近在docker上布置了一个含有puppeteer包的node服务,发动容器后呈现下图中的过错。

docker上puppeteer运行失败的问题
意思便是找不到可运转chorme浏览器。所以处理思路很清楚:便是想办法在 docker环境中把浏览器装置上
尽管看起来简单,可是我在实践中仍是踩了不少坑,比如puppeteer官网上的的【故障扫除】文中尽管写了docker上的运转计划, 可是实测时代码压根跑不起来。然后我又在网上查询其他材料,有些是依据含有puppeteer的镜像构建的,不符合我的要求,由于我期望镜像巨细和镜像的puppeteer版别能够自己操控, 就没有采用并测验。其他依据体系镜像的计划也试了跑不起来,基本都是在装置浏览器时装置失败。 不过在我阅读了很多材料后,仍是探索出了一个成功可行的装置计划,所以本文首要叙述的便是如何依据我的计划处理docker上puppeteer的装置问题。

处理计划

本文用一个简单的案例,来叙述具体怎么处理docker上的puppeteer(本文版别是18.x.x)

  1. 首要找个空文件夹,执行npm init -ynpm install puppeteer-core koa

  2. 接着创立一个demo,在根目录新增index.js,内容如下

const puppeteer = require('puppeteer-core');
const Koa = require('koa');
const app = new Koa();
app.use(async ctx => {
  const browser = await puppeteer.launch({
    headless: true,
    executablePath: 'google-chrome-stable', // 运用额外装置的谷歌浏览器
    args: ['--no-sandbox'] // 这个参数不加,会运转报错
  });
  // 测验用无头浏览器爬取百度的网站log0
  const page = await browser.newPage();
  await page.goto('https://baidu.com');
  const bodyHandle = await page.$('[rel=icon]')
  const data = await page.evaluate(dom => dom.href, bodyHandle);
  await bodyHandle.dispose()
  await browser.close();
  // 假如测试通过,接口会回来百度logo
  ctx.body = {
    code: 200,
    data: data
  };
});
app.listen(3000)
  1. 再创立一个sources.list文件
# 阿里云镜像http://developer.aliyun.com/mirror/?serviceType=&tag=&keyword=debian
# 这儿改成http地址,否则apt-get update会呈现No system certificates available报错
deb http://mirrors.aliyun.com/debian/ buster main non-free contrib
deb-src http://mirrors.aliyun.com/debian/ buster main non-free contrib
deb http://mirrors.aliyun.com/debian-security buster/updates main
deb-src http://mirrors.aliyun.com/debian-security buster/updates main
deb http://mirrors.aliyun.com/debian/ buster-updates main non-free contrib
deb-src http://mirrors.aliyun.com/debian/ buster-updates main non-free contrib
deb http://mirrors.aliyun.com/debian/ buster-backports main non-free contrib
deb-src http://mirrors.aliyun.com/debian/ buster-backports main non-free contrib

4.然后创立最关键的Dockerfile

FROM node:16-slim
# 替换阿里云镜像
COPY sources.list /etc/apt/sources.list
# 单独装置谷歌浏览器
RUN apt-get update   
RUN apt-get install curl -y
RUN curl -LO https://dl.google.com/linux/direct/google-chrome-stable_current_amd64.deb
RUN apt-get install -y ./google-chrome-stable_current_amd64.deb
RUN rm google-chrome-stable_current_amd64.deb 
# 目前咱们用的是puppeteer-core包。假如项目用的是puppeteer包,请撤销下面注释。
# ENV PUPPETEER_SKIP_CHROMIUM_DOWNLOAD=true 
# 复制文件到镜像的app目录下
COPY index.js /app/
COPY package.json /app/
# 装包
WORKDIR /app
RUN npm set registry http://registry.npm.taobao.org/ 
RUN npm install
EXPOSE 3000
ENTRYPOINT node index.js

这儿有几点需要说明一下,第一点,咱们的用的node:16-slim是依据debian体系的,apt-getdebian体系上的软件装置东西, 类型于前端的npm,假如直接用apt-get装包会非常的慢,大约要一个多小时,所以我从阿里云镜像站找了debian体系的下载镜像(PS:我之前测验的计划, 失败原因也是由于恳求外网下载超时,或衔接不上), 来提高下载速度,node:16-slim对应的debian版别是10.x,能够在容器里执行cat /etc/debian_version查看debian的版别, 然后去阿里云镜像,复制对应版别的sources.list内容, 放到项目的sources.list文件。DockerfileCOPY sources.list /etc/apt/sources.list这行的效果便是复制项目文件替换镜像里的sources.list,以便运用 阿里云镜像进行下载
第二点,咱们demo里用的是puppeteer-core包,与puppeteer的区别是里边不含浏览器依赖的, 理论上docker环境中也用不了puppeteer包捆绑装置的浏览器,否则也不会呈现这篇文章。假如你的项目里用的是puppeteer, 就需要在Dockerfile里加上环境变量ENV PUPPETEER_SKIP_CHROMIUM_DOWNLOAD=true 来防止装置捆绑的浏览器

  1. 全部准备就绪后,咱们运转容器试一下
docker build . -t pptr
docker run -p 3000:3000  --name pptr -d pptr:latest

然后恳求http://127.0.0.1:3000,接口会正常回来百度网站的logo,说明puppeteer在docker环境上成功运转了

跋文

回忆处理计划,咱们能够发现,这个问题本质上便是要学会如何在服务器上装置浏览器,所以你的项目假如是布置centos,ubantu这些环境, 也能够作为参阅,然后依据体系提供的装包东西,把它的镜像源换成国内的,再进行装置浏览器即可

参阅文献

  • puppeteer官方FAQ
  • 阿里云debian镜像站
  • apt-get update 一向报证书过错 Certificate verification failed
  • 如何在依据Ubuntu 19.10和20.04的Docker中装置chromium
  • 截图的诱惑:Docker布置Puppeteer项目
  • docker 布置 puppeteer
  • Linux debian 11上装置 Google Chrome浏览器教程
  • CentOS 8 装置puppeteer 运转报错处理方式