最近项目中需要在 orange-ci 中进行利用 puppeteer.js 进行截图保存等一系列操作。那么问题马上就来了:在 orange-ci 中 puppeteer.js 如何运行?
在 orange-ci 中运行 puppeteer.js 也是基于 Linux 环境,在 Linux 环境中安装 Chromium 最长见的 2 个问题就是:
- 下载 Chromium 时,下载常常以失败告终。换个镜像源后 Chromium 能下载成功,但启动后
各种报错,是 Linux上 缺少部分依赖导致的(最新的两个版本我测试不会出现下载 Chromium 失败的情况了,旧项目使用的 5.x 版本经常失败) - 安装完需要的依赖,代码顺利运行。但截图却发现浏览器上的中文字体竟全是框框框框,缺少中文字体库
上面两个问题也可以侧面说明,将项目改用 Docker 部署的话,能避免出现本地开发正常,上线后却出现各种问题的情况。
整体计划
我首先在 KM 平台上搜索了下看看有木有前辈做了相关工作并记录下来了,发现没有找到,基于 123 上制作 docker 镜像倒是有,例如:123上制作docker镜像全教程,以ffmpeg和puppeteer实战为例,我也测试了文章里面的 puppeteer 运行镜像代码去基于 orange-ci 去运行 puppeteer,但是没有成功。所以有了这篇文章,希望可以帮助到后面的童鞋。
笔者的想法是:由于在 orange-ci 流程中可以执行各种命令,所以我可以利用一些命令来运行 js 脚本来进行 puppeteer.js 和一些相关操作。命令的具体操作内容是通过自己发布一个 cli 命令的 npm 包,在包里面实现你需要的一系列包含 puppeteer.js 截图的操作。在 orange-ci 执行命令进行 puppeteer.js 脚本操作的时候,需要依赖一个支持 puppeteer.js 运行的 docker 镜像环境(通过查阅 orange-ci 文档 可以知道,可以通过“构建一个 Docker 缓存”或者“使用 docker 自定义构建环境”来实现)。
所以我们可以先制作一个能够运行 puppeteer.js 的运行镜像,然后给镜像加上 orange-ci 的支持,把镜像 上传 CSIG 容器平台,然后跑 ci 的时候,基于这个镜像环境去跑就行了。
制作 puppeteer 运行镜像
在制作 puppeteer 运行镜像的过程中,真是一波三折,遇到过各种个样的问题。
方案一
最初我想的是制作一个内部不包含 puppeteer.js 本身的镜像,然后利用 cli 中的 puppeteer.js ,cli 中只安装 puppeteer-core,通过调用 puppeteer.launch 时的 executablePath 配置引入自行下载的 Chromium,这样还能加快 npm install 时候的构建速度。
这个方案本身没有问题,虽然在安装好 puppeteer.js 并进行测试的时候遇到过各种坑,但是都解决了,最后卡在最后一步,在 orange-ci 中一直找不到 executablePath 配置的浏览器路径,并且还需要单独处理不同版本下的浏览器问题,所以就暂时搁置了该方案。
方案二
方案一先暂停告一段落,先进行方案二。当时通过查找资料,找到了一份 Dockerfile 代码(,对 Dockerfile 不熟悉的童鞋可以看我的另一篇小结:docker 常用命令解析和使用小坑):
1 | # 基于`alpine`版本的`node`10 |
构建命令:docker build -t node-puppeteer:puppeteer1_11-node10-alpine .
运行命令:docker run -it --rm node-puppeteer:puppeteer1_11-node10-alpine sh
我进行了一些简单修改,加入了测试代码,发现是可以直接成功运行 puppeteer.js 并且截图成功的,上面的 COPY ./puppeteer.js .
是拷贝我自己的测试代码,你可以自己写或者用原来作者提供的,具体请见:构建 puppeteer docker 镜像。
我把镜像上传至 TKEx-CSIG 容器平台,并且进行测试也可以打印出我要的信息了,到现在为止一切顺利,接下来要加上支持 orange-ci 的运行环境了,这个镜像依赖的环境是 node:10.15.2-alpine
,基于 alpine 版本的 node 10。那么问题来了:直接把依赖镜像修改为支持 orange-ci 的镜像,找不到合适的基础镜像咋办?没有合适的基础镜像,那就只能自己搭一个或者在当前的 Dockerfile 文件中进行安装 orange-ci 的运行环境。
但是我在当前 Dockerfile 中进行修改和安装一些需要的软件时,却一直失败(可能是我哪里写错了~~),例如我在上述代码中通过 apk
安装 vi 或者 vim,因为当前容器中没有 vi 或 vim,不好在命令行编辑文件(只能只用 echo
命令),以及测试的时候修改也不方便(后续遇到这种情况我是采用 docker cp
命令进行复制操作的)。附:Alpine镜像使用。
并且我发现基于当前 Dockerfile 的镜像中 puppeteer.js 的版本很低(1.11.0),chrome 的版本也比较低,然后当前项目里面使用的是最新版本,想升级但是暂时没找到合适的下载路径。所以方案二我暂时也搁置了,当然如果适合的童鞋可以直接使用。
方案三
方案三我是想着在当前使用的 orange-ci 基础镜像上自己写 dockerDockerfile 来创建环境(开始就想了几种方案,所以才会暂时先搁置前面遇到问题的方案)。但我在寻找前面方案问题和报错的解决办法的过程中,发现 puppeteer.js 官方有一个 Troubleshooting.md 文件中记录了一些可能会坑,以及 Running Puppeteer in Docker。所以我直接使用官方的 Dockerfile 文件创建了一个,经过测试是可以成功在镜像中运行 puppeteer.js(再次说明认真查看官方资料很重要!!!)。
类似于方案二,我需要加上 orange-ci 的运行环境,我直接把官方的镜像的基础镜像源替换为了我当前 orange-ci 所依赖的基础景象源,我直接把 FROM node:12-slim
替换为 csighub.tencentyun.com/orange-ci/default-env
,所有内容为:
1 | FROM csighub.tencentyun.com/orange-ci/default-env |
经过本地测试和 devCloud 上的测试,该方案可以完美的支持我需要的运行环境,并且和方案二一样自带了 puppeteer.js,可以直接就进行测试,不需要额外安装,主要部分终于大功告成…
这里需要注意两个问题:
- 若你使用的项目里面还单独安装了 puppeteer.js 的话,那项目里面的代码会直接调用 package.json 里面的 puppeteer.js,这里要确定自己安装的 puppeteer.js 正常安装了正确的 Chromium,否则还是会报错不能成功打开浏览器。
- 如果在会报错
Error: Failed to launch the browser process! spawn chrome.exe ENOENT...
,可能是你没有加入在去沙箱环境的 args 配置:1
2
3const browser = await puppeteer.launch({
args: ["--no-sandbox", "--disable-setuid-sandbox"]
});
将镜像上传至 TKEx-CSIG 容器平台
这个步骤有可以直接看官方文档,文档已经写的非常详细啦,上传完毕后可以直接修改 orange-ci 的 FROM 镜像源为你自己的镜像源,也可以像我一样再在DevCloud 上测试测试。
这里附我测试 puppeteer.js 的测试代码(项目内容相关逻辑已经删除):
1 | const puppeteer = require('puppeteer'); |
以上就是本次基于 orange-ci 环境,制作 puppeteer 运行镜像,所经历的坎坷。其实中间还遇到过很多各种报错,以及涉及到一些不同环境下安装依赖库、安装 Chromium,中文字体支持等遇到的问题,这里就不一一展示出来了~~