发布的尼尔·布鲁克斯在2019年6月27日

编译wkhtmltopdf使用在一个AWS Lambda函数与Bref比你想的要容易得多

在MyBuilder我们最近有机会工作在一个新项目,这当然意味着我们能够玩的新玩具我们想试用一段时间。

我们需要提取一个独立的PDF生成服务在另一个项目我们已经做了一些工作。这是一个完美的候选人运行在AWSλ,因此也终于给了Bref生产一试。

之前的项目使用时髦的基于模板的生成报告的HTML输出,和我们有一些更多的项目也使用相同的解决方案。

因为我们知道我们不能预测的交通量服务在任何给定时间(尽管夜间可能会看到零流量),我们知道它将需要能够快速规模向上和向下。为了保持清洁和独立,我们也想避免将该服务在我们常规的web服务器。

法斯/ Serverless

法斯/ serverless是一个很好的候选人这些类型的服务(Amazon的法斯提供的被称为λ)。法对你推动你的代码到云,它坐落在等待某种事件(这可能是一个HTTP请求,或一个事件,如一个条目被添加到一个队列,或者任意数量的AWS让你反应)。当你等待的事件发生时,法斯提供者调用您的代码,然后返回响应。

关键的一点是,虽然你的代码是坐着等待一个事件发生,你不要收费。你只需要支付资源代码使用虽然它实际上是运行。此外,调用的成本。方便,法斯提供者还将为您处理扩展。

考虑到整个网站往往只是空闲等待下一个web请求的服务器上,使用这种方法意味着你可以有效地关闭所有您的web服务器,在很大程度上消除你的托管费用。然而,对于本例,我们只是需要对事件做出反应亚马逊SNS

Serverless PHP

Bref是一个开源项目,旨在帮助PHP开发人员得到他们的应用程序运行在λ。λ利用一个系统上运行PHP AWS介绍在2018年底,

层系统听起来令人困惑,但必要的外卖是一层作为一个程序或二进制可以“安装”到Lambda函数依赖,只要包括在你的配置法。你可以包括多个层Lambda函数(5)。

我假设λ的基准面的熟悉以及知识和本文的其余部分的层。如果你发现很难遵循的概念我强烈建议你去试一试与Bref部署示例应用程序首先帮助你了解这些东西的一起玩。

滚自己的层

正如上面提到的,我们在PHP应用程序中使用爽快的将HTML转换为PDF。然而,时髦的依赖的wkhtmltopdf二进制安装在服务器上运行的PHP应用程序。

Bref PHP层提供了基础让我们运行我们的应用程序代码,但它不提供wkhtmltopdf二进制文件,我们需要做实际HTML-to-PDF转换。

当我们检查了wkhtmltopdf下载页面我们发现没有亚马逊Linux本地版本。因此我们有一些选择对我们来说,这是:

  1. 在互联网上找到一个预编译Lambda-compatible二进制和包括它与我们的应用程序代码
  2. 在互联网上找到一个预编译Lambda-compatible二进制和创建自己的λ层
  3. 编译wkhtmltopdf二进制自己&创建一个层

我们担心在互联网上找到预编译的二进制文件&包括那些在我们的代码是有原因的:

  1. 我们不能100%保证谁创造了二进制是完全值得信赖的
  2. Lambda-compatible预编译的二进制文件我们发现都至少有一个小版本过时

正如你可能已经猜到的,本文的标题,我们选择了3。我很兴奋,因为尽管我已经导致Bref一段时间,我没有编译任何层(尽管它是我自己想的一个问题Bref松弛社区)。我应该提醒你,我们第一次做这个花了几个小时,我们走错了路几次。然而,我们最终找到了工作。这就是我们如何实现我们的目标。

开始的旅程

wkhtmltopdf有一个单独的用于构建和包装二进制的回购和指令。因为我们知道我们的建筑AmazonLinux,我们需要确保我们有码头工人安装和运行(根据wkhtmltopdf指令)。

我们还需要确保我们有python-yaml安装(pip安装pyyaml如果你在一个Mac),以及gitp7zip

构建过程需要你都包装和源库可用你的主机,所以首先创建一个wkhtmltopdf-build一起把所有的目录。

mkdirwkhtmltopdf-build& &cdwkhtmltopdf-build

其次,克隆到两个存储库wkhtmltopdf-build父目录。

git克隆git@github.com: wkhtmltopdf / packaging.git
git克隆git@github.com: wkhtmltopdf / wkhtmltopdf.git

这将导致以下目录结构:

wkhtmltopdf-build包装/ | - | - wkhtmltopdf

确保它是独立的

我们需要创建一个静态构建,这意味着所有的依赖项wkhtmltopdf独立存在于二进制本身(基本上,我们不能依赖AmazonLinux操作系统为我们提供任何东西)。这些都是由wkhtmltopdf“链接”Git存储库(子)。安装它们,cdwkhtmltopdf目录并运行:

git子模块更新

这把qt图书馆到这个项目中。

令人信服的wkhtmltopdf /包装承认亚马逊Linux

到目前为止最困难的部分创建这整件事是弄清楚如何使用/构建。脚本构建自己的二进制。一旦我们发现规则我们可以归结为几个简单的步骤:

从现在开始将在我们所做的一切包装目录,让我们直接进入:

cd包装

现在我们需要编辑build.yaml并添加自己的AmazonLinux配置。我知道AmazonLinux是基于RedHat / CentOS,幸运的是已经有一个吗centos64配置文件中,所以我应该就能够复制和修改。

首先,我将创建一个条目AmazonLinux64。我可以离开指令一样centos64的包应该是兼容的。

然而,我需要改变容器是一个版本的AmazonLinux操作系统。的λ码头工人提供图片,所以我们可以包括那些。

amazonLinux64::码头工人/ Dockerfile.centos64arg游戏::lambci /λ:构建

一切可以离开了,所以我的最后amazonLinux64配置应该如下:

amazonLinux64::码头工人/ Dockerfile.centos64arg游戏::lambci /λ:构建输出:rpm:x86_64依赖:>ca证书fontconfigfreetype的glibclibjpeglibpnglibstdc + +libX11libXextlibXrenderopensslxorg - x11 -字体- 75 dpixorg-x11-fonts-Type1zlib

得到了发动机运行

接下来,我们需要创建的集装箱码头工人的实际编译wkthmltopdf二进制,构建脚本为我们提供:

。/构建docker-images amazonLinux64

开始构建

现在我们已经准备好让我们的二进制。的构建为我们提供了一个脚本compile-docker选项将在我们的源代码和编译AmazonLinux容器。请注意,有一个package-docker命令将创建一个rpm程序文件(或. deb如果是Debian / Ubuntu系统),但我们需要实际的二进制文件,而不是一个安装程序。

它要求建立目标的名称(amazonLinux64源代码(),相对路径. . / wkhtmltopdf),你想要的二进制。我选择wkhtmltopdf-bin

。/构建compile-docker amazonLinux64 . ./ wkhtmltopdf wkhtmltopdf-bin

接下来发生的是,码头工人旋转一个实例,安装的所有依赖项,并且运行编译器。这可能需要一些时间,所以这是一个好主意之前踢了你去午餐或床上…

创建一个二进制的层

一旦wkhtmltopdf已经产生二进制(您应该能够找到它wkhtmltopdf-bin / wkthtmltox / bin /),你需要包成一层包含在你的λ。我们不关心wkhtmltoimage二进制也产生了,所以我们就拉上拉链单一PDF格式的二进制文件。

邮政编码- rwkhtmltopdf.zipwkhtmltopdf

现在我们需要上传AWS的zip文件包含在我们的Lambda函数。您可以使用Lambda控制台如果你喜欢一个可视化界面,但是考虑到我们所做的一切通过命令行这里我们不妨使用AWS CLI

awsλpublish-layer-version——图层名称mybuilder-wkhtmltopdf——描述“独立wkhtmltopdf二进制”——压缩文件wkhtmltopdf.zip

命令将返回一个响应JSON。要注意的是LayerVersionArn:

{“LayerVersionArn”:“攻击:aws:λ:一来:<编辑>:层:mybuilder-wkhtmltopdf: 1”}

(注意,这里还有一个LayerArn,但我们需要LayerVersionArn因为它指向的实际版本我们创建的层)

现在,在我的template.yaml文件我可以包括我们发表在我的层配置以及基础PHP层由Bref提供:

资源:PdfService:类型:AWS: Serverless:函数属性:#……:- - - - - -攻击:aws:λ:一来:<编辑>:层:mybuilder-wkhtmltopdf: 1- - - - - -攻击:aws:λ:eu-west-1:209497400698:层:php-73:7”

如何调用二进制

在AWS使图层的内容访问/ opt。所以我们需要告诉时髦的二进制通过指向自己的编译的版本:

< ? php使用Knp \时髦\ Pdf;时髦的美元=Pdf(' / opt / wkhtmltopdf ');

你做什么与生成的PDF后是取决于你。一个想法可能会将它推到一个S3 bucket以后你可以下载它,或者你可以直接向你的客户在你的电子邮件λ服务(AWS SES可能派上用场)。

完成了

在这里我们钻研第一次尝试编译的二进制包特别AmazonLinux环境中,然后创建一个层的包,我们可以包括在我们的Lambda函数和使用。包装层是迄今为止比编译它那么复杂。

我们发现这是一个真的有用的练习对于理解如何创建层为λ,以及如何使用它们在serverless Bref之上的PHP应用程序。这个用例是一样复杂的我们可以让它,当然我省略了实现细节等我们收到了HTML想转换成PDF格式,和解码。这些方面更一般serverless文章和覆盖AWS的文档

显然对于这个项目我们需要包括wkhtmltopdf用例的程序,但是很多额外的层不需要任何额外的软件,他们可能只需要改变的运行时配置PHP调用。这种情况下比我们进入更简单,因为你可以跳过整个编译步骤就压缩了自己的运行时配置(我们会跟进与另一篇关于!)。

出去,PDF-ify。

工作在MyBuilder和Instapro

我们需要有经验的软件工程师谁爱他们的手艺,想要分享他们辛苦赚来的知识。

查看职位空缺
评论的Disqus