概述
Export to PDF 服务是一个服务器端组件,用于将 HTML 内容转换为 PDF 文件。它在主机基础设施内部署于本地环境,可通过两种方式使用:
作为 TinyMCE 编辑器中 Export to PDF 插件的后端。
直接通过其 REST API,独立于编辑器使用。
若要使用 TinyMCE 8.4.0 或更高版本配合 Export to PDF 插件,本地 Docker 镜像必须支持 v2 API(
/v2/convert/html-pdf)。请使用最新镜像或兼容 v2 的版本。有关版本详情,请参阅 变更日志。
要在本地运行 Export to PDF Converter 服务,需要有效的服务许可证密钥。此密钥与 TinyMCE 编辑器许可证密钥不同。此外,还需要访问令牌才能访问 Tiny Cloud Docker 仓库并拉取 Docker 镜像。有关更多信息,请参阅 服务许可证密钥。
开始使用前,请联系 Tiny 支持团队获取试用服务许可证密钥和 Docker 访问令牌。
在本地运行 Export to PDF 服务的唯一要求是容器运行时或编排工具,例如 Docker、Kubernetes 或 Podman。
要求
要运行 Export to PDF On-Premises,需要一个 Docker 环境。或者,可以使用云提供商提供的 CaaS(容器即服务),如 AWS ECS、Google GKE 或 Azure ACS。
影响 Export to PDF On-Premises 性能的因素有很多。最主要的是导出内容的尺寸、图像尺寸以及并发请求的数量。此外,由于您的应用程序可能需要优先考虑快速响应时间,或者需要处理高负载,因此无法提供一套适用于所有用例的推荐服务器规格。
假设响应时间在 10 秒以内,一台服务器(2 CPU、2GB RAM)搭配 1 个 Docker 容器可以处理:
最多 40 个并发请求,平均内容为 1 页 A4 纸(约 1k 字符和 1 张图像)
最多 25 个并发请求,平均内容为 5 页 A4 纸(约 7,5k 字符和 5 张图像)
最多 10 个并发请求,平均内容为 20 页 A4 纸(约 30k 字符和 20 张图像)
上述并发请求数量并非 Export to PDF On-Premises 实例的硬性限制。它可以处理更多并发请求,但响应时间会延长。
高可用性
一个带有 Export to PDF On-Premises 的 Docker 容器可以利用机器上的额外 CPU 资源。若要在单台机器上扩展应用程序,可增加 CPU 数量,但 Tiny 建议至少在三个主机上进行扩展,以确保系统的可靠性。
在多台机器上进行扩展时,需要使用负载均衡器,如 HAProxy 或 NGINX(参见 SSL 通信指南中的负载均衡器配置示例)。当然,也可以使用任何云提供商进行扩展,例如 Amazon ECS、Azure Container Instances 或 Kubernetes。
如果您有关于 Export to PDF On-Premises 用例所需服务器资源的任何问题,请联系我们。
安装
运行 Export to PDF 本地服务需要两个独立的凭据:
Docker 仓库访问令牌:用于向 Tiny Docker 仓库认证并拉取服务镜像。
服务许可证密钥:用于在运行时启用服务。此密钥与 TinyMCE 编辑器许可证密钥不同。
支持的技术
该应用程序默认以 Docker 镜像形式提供。
它可以使用任何 Open Container 运行时工具运行,例如 Kubernetes、OpenShift、Podman、Docker 等。
有关运行 Export to PDF On-Premises 所需的硬件和软件要求的更多信息,请参阅要求指南。
使用 Docker 容器设置应用程序
登录 Docker 仓库并使用提供的访问令牌获取 Docker 镜像。
使用
docker或docker-compose对应用程序进行容器化。使用演示页面验证应用程序是否正常工作。
使用 docker 进行容器化的示例
登录 Docker 仓库:
docker login -u tiny -p [access-token] registry.containers.tiny.cloud
拉取 Docker 镜像:
docker pull registry.containers.tiny.cloud/pdf-converter-tiny:[version]
要查看所有可用的 Docker 镜像版本,请参阅 pdf-converter-tiny 的变更日志。
为确保能够访问服务的最新版本,Tiny推荐在拉取镜像时使用
latest标签。
启动 Docker 容器:
docker run --init -p 8080:8080 -e LICENSE_KEY="$PDF_LICENSE_KEY" registry.containers.tiny.cloud/pdf-converter-tiny:[version]
将 $PDF_LICENSE_KEY 替换为服务许可证密钥,或将 PDF_LICENSE_KEY 设置为环境变量。有关详情,请参阅 使用特定于服务的环境变量。
如果使用授权,请提供 SECRET_KEY:
docker run --init -p 8080:8080 -e LICENSE_KEY="$PDF_LICENSE_KEY" -e SECRET_KEY=[your_secret_key] registry.containers.tiny.cloud/pdf-converter-tiny:[version]
有关使用授权的更多信息,请参阅授权部分。
使用 docker-compose 进行容器化的示例
创建 docker-compose.yml 文件:
version: "3.8" services: pdf-converter-tiny: image: registry.containers.tiny.cloud/pdf-converter-tiny:[version] ports: - "8080:8080" restart: always init: true environment: LICENSE_KEY: "${PDF_LICENSE_KEY}" # Secret Key is optional SECRET_KEY: "secret_key" # Custom request origin is optional CUSTOM_REQUEST_ORIGIN: "https://your_custom_origin"有关
SECRET_KEY使用的详情,请检查授权部分。运行:
docker compose up
如果没有正确的
LICENSE_KEY,应用程序将无法启动。请在.env文件或 shell 环境中设置PDF_LICENSE_KEY为有效的服务许可证密钥。
如果许可证无效,日志中将显示错误的许可证密钥信息,且应用程序将无法运行。
出于安全考虑,建议使用唯一且难以猜测的字符串覆盖 SECRET_KEY 变量。
如果特定基础设施启用了严格的 CORS,则使用
CUSTOM_REQUEST_ORIGIN变量来设置转换器发起的请求的来源。默认值为https://pdf-internal。
Windows 字体支持
如果在 PDF 文件中使用了 Windows 字体(如 Calibri、Verdana 等),请使用 pdf-converter-windows-tiny Docker 镜像并在 Windows 操作系统上运行它。
有关更多详情,请参阅字体部分。
后续步骤
使用 http://localhost:8080/v1/convert 端点导出 PDF 文件。查看授权部分以了解更多关于令牌和令牌端点的信息。
使用位于 http://localhost:8080/demo 的演示页面生成示例 PDF 文件。
有关更多详情,请参阅位于 http://localhost:8080/docs 的 Export to PDF REST API 文档。
字体
在撰写文档时,能够使用多种不同的字体对用户来说可能非常重要。
使用合适的字体可以改变文档的外观并强调其风格。
Export to PDF Converter 允许使用 Web 字体,这使集成商能够使用标准操作系统字体或使用自定义字体,而无需使用 CSS 导入它们。
以下是镜像中包含的基本字体列表:
OpenSans-Bold.ttf OpenSans-BoldItalic.ttf OpenSans-ExtraBold.ttf OpenSans-ExtraBoldItalic.ttf OpenSans-Italic.ttf OpenSans-Light.ttf OpenSans-LightItalic.ttf OpenSans-Regular.ttf OpenSans-Semibold.ttf OpenSans-SemiboldItalic.ttf
但是,可以通过以下两种方式向 Export to PDF Converter 添加其他字体:
使用类 Unix 环境的 PDF-Converter 镜像
registry.containers.tiny.cloud/pdf-converter-tiny并将字体目录挂载到其中。请参阅“向 PDF Converter 添加自定义字体”部分。
使用 Windows PDF-Converter 镜像
registry.containers.tiny.cloud/pdf-converter-tiny,并将运行该容器的 Windows 操作系统上的字体目录挂载到容器中。请参阅“在 PDF Converter 中使用 Windows 字体”部分。
挂载卷内的字体将安装在 Docker 镜像的操作系统上。仅支持.ttf和.otf字体格式。如果使用其他字体格式,则需要先将其转换为支持的格式,或者使用如 Web Fonts 之类的字体。
在安装到 Docker 容器之前,请确保这些转换后的字体可以在您的本地机器上安装并使用。
向 PDF Converter 添加自定义字体
如果 PDF 文件中使用了自定义字体,请使用 pdf-converter-tiny Docker 镜像,并将包含自定义字体的目录挂载到在类 Unix 系统(包括带有 WSL 后端的 Docker on Windows)上运行的 PDF Converter 应用程序中。
registry.containers.tiny.cloud/pdf-converter-tiny Docker 镜像需要在类 Unix 操作系统上运行,并挂载 ~/your_fonts_dir:/usr/share/fonts/your_fonts_dir 卷。
在类 Unix 操作系统上启动 Docker 容器的示例:
docker run --init -v ~/your_fonts_dir:/usr/share/fonts/your_fonts_dir -p 8080:8080 -e LICENSE_KEY="$PDF_LICENSE_KEY" registry.containers.tiny.cloud/pdf-converter-tiny:[version]
在 PDF Converter 中使用 Windows 字体
如果在 PDF 文件中使用了 Windows 字体(如 Arial、Verdana 等),请使用 pdf-converter-windows-tiny Docker 镜像,该镜像允许您在 Windows 操作系统的机器上运行应用程序并挂载系统字体。
您只需在 Windows 操作系统上运行 registry.containers.tiny.cloud/pdf-converter-tiny Docker 镜像,并挂载 C:\Windows\Fonts:C:\Windows\Fonts 卷即可。
在 Windows 操作系统上启动 Docker 容器的示例:
docker run -v C:\Windows\Fonts:C:\Windows\Fonts -p 8080:8080 --env LICENSE_KEY="$PDF_LICENSE_KEY" registry.containers.tiny.cloud/pdf-converter-windows-tiny:[version]
授权
要启用授权,请在安装期间设置 SECRET_KEY 环境变量。
如果设置了 SECRET_KEY 变量,则所有请求都必须包含一个使用该密钥签名的 JWT (JSON Web Token) 头部。令牌应作为发送到 Export to PDF REST API 的每个请求的 Authorization 头部的值传递。
如果在安装期间未设置 SECRET_KEY,则 Export to PDF On-Premises 在向 Export to PDF REST API 发送请求时不需要任何包含令牌的头部。然而,不建议在公共网络中运行 Export to PDF On-Premises 时跳过授权。生成令牌
Tiny 建议使用 jwt.io 上列出的库来生成令牌。当满足以下条件时,令牌被视为有效:
它使用与传递给 Export to PDF On-Premises 实例相同的
SECRET_KEY签名,它在过去 24 小时内创建,
它不是在未来发行的(即 iat 时间戳不能晚于当前时间),
它尚未过期。
如果特定用例涉及从后端服务器发送请求,则可以像下面的请求示例所示在本地生成 JWT 令牌。
对于编辑器插件或其他前端用途,应创建一个令牌端点,为授权用户返回有效的 JWT 令牌。
端点实现示例。const express = require( 'express' );
const jwt = require( 'jsonwebtoken' );
const SECRET_KEY = 'secret_key';
const app = express();
app.use( ( req, res, next ) => {
res.setHeader( 'Access-Control-Allow-Origin', '*' );
res.setHeader( 'Access-Control-Allow-Methods', 'GET' );
next();
});
app.get( '/', ( req, res ) => {
const result = jwt.sign( {}, SECRET_KEY, { algorithm: 'HS256' } );
res.send( result );
});
app.listen( 8080, () => console.log( 'Listening on port 8080' ) );使用编辑器插件
TinyMCE 的插件将自动从给定的 tokenUrl 变量请求令牌,并在进行导出请求时设置 Authorization 头部。
有关如何将 Export to PDF 功能添加到编辑器的详细信息,请参阅 Export to PDF 插件文档。
带 Authorization 头部的请求示例
以下示例展示了一个生成有效 JWT 令牌并将其设置为 Authorization 头部的请求:
const fs = require( 'fs' );
const jwt = require( 'jsonwebtoken' );
const axios = require( 'axios' );
const SECRET_KEY = 'secret';
const token = jwt.sign( {}, SECRET_KEY, { algorithm: 'HS256' } );
const data = {
html: "<p>I am a teapot</p>",
css: "p { color: red; }",
};
const config = {
headers: {
'Authorization': token
},
responseType: 'arraybuffer',
};
axios.post( 'http://localhost:8080/v1/convert', data, config )
.then( response => {
fs.writeFileSync('./file.pdf', response.data, 'binary');
}).catch( error => {
console.log( error );
});SECRET_KEY 是已传递给 Export to PDF On-Premises 实例的密钥。
请参阅 Export to PDF REST API 文档 以开始使用该服务。
如果使用 Postman 或 Insomnia 等 API 客户端,请在Headers选项卡中将 JWT 令牌设置为Authorization头部。不要使用内置的令牌授权,因为这会生成无效的头部,并在令牌前添加了Bearer前缀。
API 用法
Export to PDF On-Premises 转换器提供通过 Restful API 将 HTML 文档转换为 PDF 文件的能力。
API 可在 http://localhost:[port] 上访问(默认情况下 port 为 8080)。
REST API 文档位于 http://localhost:[port]/docs。或者,请参阅 https://exportpdf.api.tiny.cloud/v1/convert/docs 中的规范。如果启用了 API 授权,请提供授权令牌。更多说明可在授权部分找到。
使用额外的 HTTP 头部
如果在生成的 PDF 中使用某些资源(例如图像)需要以额外 HTTP 头部的形式传递额外的授权因素:
可以在应用程序启动时通过设置
EXTRA_HTTP_HEADERS环境变量来定义,其中值为包含所需头部的字符串化 JSON 对象。可以在发送到 PDF Converter API 的请求的
options中定义:
const data = {
html: '<p>I am a teapot</p><img src="https://secured-example-website.com/image.jpg">',
css: 'p { color: red; }',
options: {
extra_http_headers: {
authorization: 'Bearer <replace_with_your_auth_key>'
}
}
};
axios.post( 'exportpdf_service_url placeholder', data, config )
.then( response => {
fs.writeFileSync('./file.pdf', response.data, 'binary')
}).catch( error => {
console.log( error );
});在应用程序配置中和请求中定义的头部将被合并。如果同一头部在两个地方都定义了,则优先使用来自 PDF 选项的头部值,而不是来自应用程序配置的值。
SSL 通信
可以使用安全连接与 Export to PDF On-Premises 进行通信。为此,需要使用 SSL 证书设置负载均衡器,如 NGINX 或 HAProxy。
下面是 HAProxy 和 NGINX 的配置示例。
HAProxy 示例
这是一个基本的 HAProxy 配置:
global
daemon
maxconn 256
tune.ssl.default-dh-param 2048
defaults
mode http
timeout connect 5000ms
timeout client 50000ms
timeout server 50000ms
frontend http-in
bind *:80
bind *:443 ssl crt /etc/ssl/your_certificate.pem
http-request set-header X-Forwarded-Proto https if { ssl_fc }
http-request set-header X-Forwarded-Proto http if !{ ssl_fc }
redirect scheme https if !{ ssl_fc }
default_backend servers
backend servers
server server1 127.0.0.1:8080 maxconn 32NGINX 示例
这是一个基本的 NGINX 配置:
events {
worker_connections 1024;
}
http {
server {
server_name your.domain.name;
listen 443;
ssl on;
ssl_certificate /etc/ssl/your_cert.crt;
ssl_certificate_key /etc/ssl/your_cert_key.key;
location / {
proxy_pass http://127.0.0.1:8080;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "Upgrade";
proxy_set_header Host $host;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_http_version 1.1;
}
}
}Docker 镜像不包含内置的 SSL 配置。SSL 必须由反向代理处理,该代理将请求转发到容器在 8080 端口上的 HTTP 服务。
日志
Export to PDF On-Premises 的日志写入 stdout 和 stderr。大多数日志格式为 JSON。它们可用于监控或调试目的。在生产环境中,建议将日志存储到文件中或使用分布式日志系统(如 ELK 或 CloudWatch)。
使用日志监控 Export to PDF
为了更深入地了解 Export to PDF On-Premises 的性能表现,可以使用日志进行监控。要启用此功能,请添加 ENABLE_METRIC_LOGS=true 环境变量。
日志结构
日志结构包含以下信息:
handler:操作的统一标识符。使用此字段来识别调用。traceId:唯一的 RPC 调用 ID。tags:以分号分隔的标签列表。使用此字段过滤指标日志。data:包含额外信息的对象。它可能因不同的传输方式而异。data.duration:请求持续时间(毫秒)。data.transport:请求传输的类型。可能是 http 或 ws (websocket)。data.status:请求状态。可以是 success、fail 或 warning。data.statusCode:HTTP 状态码标准中的响应状态。
此外,对于 HTTP 传输,还包括以下信息:
data.url:URL 路径。data.method:请求方法。
如果发生错误,data.status 将为 failed,且 data.message 将包含错误消息。
HTTP 传输的日志示例:
{
"level": 30,
"time": "2021-03-09T11:15:09.154Z",
"msg": "Request summary",
"handler": "convertHtmlToPdf",
"traceId": "85f13d92-57df-4b3b-98bb-0ca41a5ae601",
"data": {
"duration": 2470,
"transport": "http",
"statusCode": 200,
"status": "success",
"url": "/v1/convert",
"method": "POST"
},
"tags": "metrics"
}Docker
Docker 具有内置的日志记录机制,可捕获容器输出的日志。默认日志驱动程序将日志写入文件。
使用该驱动程序时,使用 docker logs 命令显示容器的日志。可以添加 -f 标志以实时查看日志。有关日志命令的更多信息,请参阅 官方 Docker 文档。
当容器长时间运行时,日志可能会占用大量空间。为避免此问题,请确保启用日志轮转。这可以通过 max-size 选项设置。分布式日志
如果运行多个 Export to PDF On-Premises 实例,建议使用分布式日志系统。它允许在一个地方查看和分析所有实例的日志。
AWS CloudWatch 和其他云解决方案
如果在云中运行 Export to PDF On-Premises,最简单且推荐的方法是使用所选提供商提供的服务。
以下是一些可用的服务:
AWS:CloudWatch
Google Cloud:Cloud Logging
Azure:Azure Monitor
要在 AWS ECS 中使用 CloudWatch,必须预先创建日志组,并将日志驱动程序更改为 awslogs。当日志驱动程序配置正确后,日志将直接流式传输到 CloudWatch。
logConfiguration 可能如下所示:
"logConfiguration": {
"logDriver": "awslogs",
"options": {
"awslogs-region": "us-west-2",
"awslogs-group": "tinysource",
"awslogs-stream-prefix": "tiny-pdf-converter-logs"
}
}有关更多信息,请参阅 使用 awslogs 日志驱动程序 文章。
本地化解决方案
如果使用特定的基础设施(如自有环境)或因某些原因无法使用提供商提供的服务,可以使用一些本地化分布式日志系统。
有许多可用的解决方案,包括:
这是基于 Elasticsearch、Logstash 和 Kibana 构建的堆栈。在此配置中,Elasticsearch 存储日志,Filebeat 从 Docker 读取日志并将其发送到 Elasticsearch,而 Kibana 用于查看它们。由于日志已经是结构化数据,因此不需要 Logstash。
它使用专用的 Docker 日志驱动程序 发送日志。它具有内置的前端,但也可以与 Elasticsearch 和 Kibana 集成以实现更好的过滤。
它使用专用的 Docker 日志驱动程序发送日志。它具有内置的前端,还需要 Elasticsearch 来存储日志以及 MongoDB 数据库来存储配置。
配置示例
示例配置使用 Fluentd、Elasticsearch 和 Kibana 从 Docker 捕获日志。
在运行 Export to PDF On-Premises 之前,请先准备日志服务。为了本示例的目的,使用 Docker Compose。在 docker-compose.yml 文件中创建 fluentd、elasticsearch 和 kibana 服务:
version: '3.7'
services:
fluentd:
build: ./fluentd
volumes:
- ./fluentd/fluent.conf:/fluentd/etc/fluent.conf
ports:
- "24224:24224"
- "24224:24224/udp"
elasticsearch:
image: docker.elastic.co/elasticsearch/elasticsearch:6.8.5
expose:
- 9200
ports:
- "9200:9200"
kibana:
image: docker.elastic.co/kibana/kibana:6.8.5
environment:
ELASTICSEARCH_HOSTS: "http://elasticsearch:9200"
ports:
- "5601:5601"要将 Fluentd 与 Elasticsearch 集成,首先需要在 Fluentd 镜像中安装 fluent-plugin-elasticsearch。为此,创建一个名为 fluentd/Dockerfile 的文件,内容如下:
FROM fluent/fluentd:v1.10-1 USER root RUN apk add --no-cache --update build-base ruby-dev \ && gem install fluent-plugin-elasticsearch \ && gem sources --clear-all
接下来,在 fluentd/fluent.conf 文件中配置输入服务器和到 Elasticsearch 的连接:
<source>
@type forward
port 24224
bind 0.0.0.0
</source>
<match *.**>
@type copy
<store>
@type elasticsearch
host elasticsearch
port 9200
logstash_format true
logstash_prefix fluentd
logstash_dateformat %Y%m%d
include_tag_key true
type_name access_log
tag_key @log_name
flush_interval 1s
</store>
<store>
@type stdout
</store>
</match>现在服务已准备好运行:
docker-compose up --build
当服务就绪后,启动 Export to PDF On-Premises。
docker run --init -p 8080:8080 \ --log-driver=fluentd \ --log-opt fluentd-address=[Fluentd address]:24224 \ [Your config here] \ registry.containers.tiny.cloud/pdf-converter-tiny:[version]
在浏览器中打开 Kibana。
访问地址为 http://localhost:5601/。
在首次运行时,可能会被要求创建索引。
使用
fluentd-*模式并按“Create"按钮。完成此步骤后,日志应出现在“Discover"标签页中。