URL-to-PNG 2.1.4 配置参数详解
详解 URL-to-PNG v2.1.4 全部环境变量:名单精确匹配、渲染超时、连接池指标对照、默认截图参数、加密与存储后端,并给出三套生产配置模板。
URL-to-PNG 2.1.4 配置参数详解
目标:讲清 URL-to-PNG v2.1.4 的全部服务端配置——环境变量分组详解、名单管控与渲染超时的实测行为、连接池参数与指标对照,并给出按场景分类的生产配置模板。全文配置修改与验证均已在 Ubuntu 22.04 + URL-to-PNG v2.1.4 环境实测通过(服务监听 8136 端口)。
一、环境信息
- 操作系统:Ubuntu 22.04 LTS(x86_64)
- 服务:URL-to-PNG v2.1.4(官方最新稳定版)
- 服务地址:
http://localhost:8136 - 当前生效配置:
LOG_LEVEL=info、NODE_ENV=production、METRICS=true、STORAGE_PROVIDER=filesystem、IMAGE_STORAGE_PATH=/app/images、CACHE_CONTROL=public, max-age=86400, immutable - 查询参数(调用侧配置)的逐项实测见《URL-to-PNG 2.1.4 API 使用详解》,本文聚焦服务端环境变量
二、前置条件
- 服务已按《URL-to-PNG Docker Compose 部署指南》部署并可健康检查:
curl -s http://localhost:8136/ping
# "pong"
- 了解配置生效方式:URL-to-PNG 无配置文件,全部配置经环境变量注入,修改后需重建服务进程才生效(见下一章)。
三、参数查看与修改方式
查看当前生效值的实测手段有三个:
- 启动日志——服务启动时会打印关键配置(实测日志行,JSON 格式):
{"level":30,"time":1793408061670,"pid":1,"hostname":"...","name":"url-to-png","msg":"StubStorageProvider"}
{"level":30,"time":1793408061674,"pid":1,"hostname":"...","name":"url-to-png","msg":"Allowed Domains: example.com"}
{"level":30,"time":1793408061674,"pid":1,"hostname":"...","name":"url-to-png","msg":"Server is running on port http://localhost:3089/ping"}
Server is running on port 行即 PORT 生效值;Allowed Domains/Blocked Domains 行即名单生效值(未配置时输出 (none) 语义的空值行);存储后端也有独立日志行。
-
/metrics端点核对连接池参数(POOL_MIN/POOL_MAX的生效值,见 5.3 节)。 -
行为探测——如
curl -s http://localhost:8136/metrics的 404/200 直接反映METRICS开关状态。
修改方式:编辑服务部署配置的 environment: 段后重建服务进程(重建命令与验证见《URL-to-PNG Docker Compose 部署指南》第八章)。改完必须实测验证,以 METRICS 为例:关闭后 /metrics 应变 404、开启后返回连接池 JSON。
四、参数总览
环境变量按功能分七组(默认值均经官方配置文档核对,v2.1.4):
| 分组 | 变量 | 默认值 | 一句话说明 |
|---|---|---|---|
| 通用 | LOG_LEVEL | debug | 日志级别 debug/info/warn/error |
| 通用 | NODE_ENV | development | 运行环境,生产用 production |
| 通用 | PORT | 3089 | 服务监听端口 |
| 通用 | CACHE_CONTROL | public, max-age=86400, immutable | 截图响应缓存头 |
| 名单 | ALLOW_LIST / BLOCK_LIST | 空 | 域名白/黑名单(精确匹配) |
| 渲染 | BROWSER_TIMEOUT | 10000 | 渲染超时(毫秒) |
| 渲染 | BROWSER_WAIT_UNTIL | domcontentloaded | 页面加载等待事件 |
| 连接池 | POOL_MIN / POOL_MAX | 2 / 10 | 浏览器实例常驻/上限 |
| 连接池 | POOL_IDLE_TIMEOUT_MS | 15000 | 空闲实例回收(毫秒) |
| 连接池 | POOL_MAX_WAITING_CLIENTS | 50 | 等待队列上限 |
| 默认截图参数 | DEFAULT_WIDTH / DEFAULT_HEIGHT | 250 | 默认输出尺寸 |
| 默认截图参数 | DEFAULT_VIEWPORT_WIDTH / DEFAULT_VIEWPORT_HEIGHT | 1080 | 默认视口 |
| 默认截图参数 | DEFAULT_IS_MOBILE / DEFAULT_IS_FULL_PAGE / DEFAULT_IS_DARK_MODE | false | 默认模式开关 |
| 默认截图参数 | DEFAULT_DEVICE_SCALE_FACTOR | 1 | 默认 DPR |
| 可观测 | METRICS | false | /metrics 开关 |
| 加密 | CRYPTO_KEY | 空 | AES-GCM 密钥,配置后只收加密请求 |
| 存储 | STORAGE_PROVIDER | stub | stub / filesystem / s3 / couchdb |
| 存储 | IMAGE_STORAGE_PATH | — | filesystem 后端目录 |
| 存储 | AWS_* 六项 / COUCH_DB_* 六项 | — | s3 / couchdb 后端参数 |
五、核心参数分类详解
5.1 名单管控:ALLOW_LIST 与 BLOCK_LIST
两个名单互斥使用(配了 ALLOW_LIST 就不要配 BLOCK_LIST),匹配对象是请求 URL 的 host,且为精确匹配、无通配符。被拒请求返回 403(实测):
curl -s 'http://localhost:8145/?url=https://github.com'
# {"message":"Access to this URL is forbidden"}
(上例来自临时启用 ALLOW_LIST=example.com 的验证实例,实测后已回收;名单生效时启动日志同步打印 Allowed Domains: example.com。)
精确匹配的两个实测要点(白名单 ALLOW_LIST=example.com 下):
- 主域放行:
?url=https://example.com→ 200 正常截图; - 子域不放行:
?url=https://www.example.com→ 403,日志出现Blocked request to https://www.example.com - not in allowlist。
黑名单对称:BLOCK_LIST=github.com 时 github.com 被拒、www.github.com 不在名单内可正常进入渲染流程(日志仅 Request URL host: www.github.com,无 Blocked 行)。
💡 技术拓展:域名访问控制的常见匹配策略——
策略 规则 代价 精确匹配(URL-to-PNG 采用) host 完全相等 最安全,但需穷举全部 host(含 www) 后缀匹配 允许 *.example.com配置省事,存在 evil-example.com式误配风险反向解析校验 渲染前反查 IP 归属 可防 DNS 重绑定,成本高 本服务选精确匹配:截图服务面对的是"服务端被当成 SSRF 跳板"风险,宁可配置麻烦也不能放错。
使用建议:作为内部基础设施部署时优先 BLOCK_LIST(拦内部元数据地址、已知恶意域);对外提供服务时必须 ALLOW_LIST 白名单化,否则等于开放 SSRF 探测。
5.2 渲染控制:BROWSER_TIMEOUT 与 BROWSER_WAIT_UNTIL
BROWSER_TIMEOUT(默认 10000ms)控制 goto 页面加载的超时。实测把超时压到 2000ms 后请求 example.com,约一半概率渲染超时返回 500:
{"message":"page.goto: Timeout 2000ms exceeded.\nCall log:\n - navigating to \"https://example.com/\", waiting until \"domcontentloaded\"\n"}
同一配置下重试成功(页面加载耗时有波动,2000ms 处于临界值)——超时值应按目标站点 P95 加载耗时设置并留余量,默认 10 秒覆盖绝大多数站点。另注意:page.goto 的超时只是"页面加载"上限,截图阶段的隐式资源等待不走这个超时(首图 5 秒排障结论见 D5 篇 5.7 节)。
BROWSER_WAIT_UNTIL 可选 load / domcontentloaded / networkidle,默认 domcontentloaded(DCL 即认为页面就绪,不等全部资源)。截图阶段的等待行为另见 D5 篇实测,非必要不改此值。
5.3 连接池:POOL_MIN / POOL_MAX 与 metrics 对照
连接池参数决定渲染吞吐。实测配置 POOL_MIN=2、POOL_MAX=10(默认值)时 /metrics 回显:
{"poolMetrics":{"spareResourceCapacity":8,"size":2,"available":2,"borrowed":0,"pending":0,"max":10,"min":2}}
字段与配置的对应关系:min: 2 ↔ POOL_MIN、max: 10 ↔ POOL_MAX、size 当前实例数、pending 排队数。这是容量调优的反馈闭环:pending 持续大于 0 → 调大 POOL_MAX(每实例约数百 MB 内存,量力而行)或横向扩实例;size 长期贴着 POOL_MAX 且 pending 高企 → 扩容不够。
POOL_IDLE_TIMEOUT_MS(默认 15 秒)控制空闲实例回收节奏:截图请求呈脉冲式(如每小时一批)的场景可调大,减少批次内反复建实例的开销;常驻流量平稳场景保持默认。
5.4 默认截图参数:DEFAULT_* 系列
九个 DEFAULT_* 变量为未显式传参时的兜底值。实用改造示例:把默认 250x250 换成业务常用的 1280x720 卡片图(比例语义与视口的关系实测见 D5 篇 5.2 节):
environment:
DEFAULT_WIDTH: "1280"
DEFAULT_VIEWPORT_WIDTH: "1280"
DEFAULT_VIEWPORT_HEIGHT: "720"
注意:调用方显式传参始终优先于默认值;DEFAULT_DEVICE_SCALE_FACTOR=2 一类配置适合"全局高清"需求(不改变输出像素尺寸,只加清晰度,代价是渲染与传输体积增大)。
5.5 缓存与响应头:CACHE_CONTROL
默认 public, max-age=86400, immutable:服务端缓存幂等 + 下游浏览器/CDN 24 小时不回源。实测响应头回显见 D5 篇 5.3 节。调整场景:截图需较快反映页面变化时改小 max-age(如 public, max-age=300);私有部署不想让中间层缓存时改 private, no-store。
5.6 加密:CRYPTO_KEY
留空 = 明文参数模式(常规用法)。配置后服务只接受加密请求:明文参数一律 400(实测回显 {"message":"This server must use encryption"}),合法请求形如 ?hash=str-enc:...(AES-GCM 256,密钥为 JWK JSON 串,加密串由官方 @jmondi/string-encrypt-decrypt 库生成)。反向边界也经实测:未配置密钥时传 hash 返回 {"message":"This server is not configured for encryption"}。密钥属系统级敏感凭据,注入方式用 compose 的 environment 引用宿主环境变量或 secrets,不要把密钥明文写进版本库。
5.7 存储后端:STORAGE_PROVIDER
四种后端(本文实测 filesystem):
| 后端 | 关键变量 | 行为实测 |
|---|---|---|
stub(默认) | — | 只打 StubStorageProvider 日志,不落盘;每请求真实渲染 |
filesystem | IMAGE_STORAGE_PATH | 缓存落指定目录,文件名即 imageId;重启缓存仍在(实测重启后 0.014s 命中) |
s3 | AWS_BUCKET 等 | 多实例共享缓存;本文未实测 |
couchdb | COUCH_DB_* | 已有 CouchDB 体系时用;本文未实测 |
filesystem 是单机部署的默认正确选项;缓存文件无自动清理且每种参数组合独立成文件,需定期巡检(实测缓存目录与 imageId 命名细节见 D5 篇 5.8 节)。
5.8 日志与运行环境:LOG_LEVEL / NODE_ENV / PORT
LOG_LEVEL=info生产推荐:实测 info 级仍输出 warn(名单拦截、deprecated 参数警告都是 40 级,不会被吞);排障深挖时临时开debug;NODE_ENV=production:关闭开发态行为,生产必配;PORT=3089:一般不动,改了需同步调整端口映射。
六、生产配置模板
模板一:内部平台卡片图/预览图服务(2C4G 单机,10 并发以内,filesystem 缓存)
environment:
LOG_LEVEL: info
NODE_ENV: production
METRICS: "true"
BROWSER_TIMEOUT: "15000"
POOL_MIN: "2"
POOL_MAX: "10"
POOL_IDLE_TIMEOUT_MS: "15000"
STORAGE_PROVIDER: filesystem
IMAGE_STORAGE_PATH: /app/images
CACHE_CONTROL: "public, max-age=86400, immutable"
DEFAULT_WIDTH: "1280"
DEFAULT_VIEWPORT_WIDTH: "1280"
DEFAULT_VIEWPORT_HEIGHT: "720"
适用:内容平台链接卡片、监控缩略墙。要点:METRICS 必开(容量观测);DEFAULT_* 直接落到业务常用尺寸减少缓存碎片;BROWSER_TIMEOUT 放宽到 15 秒容纳慢站点。
模板二:对外截图 API(置于网关后,白名单锁定,加密请求)
environment:
LOG_LEVEL: info
NODE_ENV: production
METRICS: "true"
BROWSER_TIMEOUT: "20000"
POOL_MIN: "2"
POOL_MAX: "10"
ALLOW_LIST: "example.com,www.example.com,docs.example.com"
CRYPTO_KEY: "${URLTOPNG_CRYPTO_KEY}" # 宿主环境变量注入,勿写明文
STORAGE_PROVIDER: filesystem
IMAGE_STORAGE_PATH: /app/images
CACHE_CONTROL: "private, max-age=3600"
适用:截图能力暴露给不可信调用方。要点:ALLOW_LIST 穷举全部 host(精确匹配,含 www);CRYPTO_KEY 启用后调用方全部走加密参数;缓存头改 private 防公共层缓存。
模板三:多实例共享缓存(4C8G × 2 实例,s3 后端)
environment:
LOG_LEVEL: info
NODE_ENV: production
METRICS: "true"
STORAGE_PROVIDER: s3
AWS_BUCKET: "urltopng-cache"
AWS_ACCESS_KEY_ID: "${AWS_ACCESS_KEY_ID}"
AWS_SECRET_ACCESS_KEY: "${AWS_SECRET_ACCESS_KEY}"
AWS_DEFAULT_REGION: "us-east-1"
AWS_FORCE_PATH_STYLE: "true"
适用:并发超过单机浏览器池上限(POOL_MAX 合计)时横向扩容,实例间共享缓存提高命中率。AWS_ENDPOINT_URL_S3 可指向任意 S3 兼容对象存储。
七、常见问题
Q1:改了环境变量怎么确认生效?
分三类核对(第三章方法):启动日志找 Server is running on port 与名单行;/metrics 对照池参数;行为探测(404/200、403/200)。改完不验证 = 没改。
Q2:名单配了却不生效?
两点实测教训:其一,名单是 host 精确匹配,example.com 与 www.example.com 是两个 host,都要列;其二,配置修改后必须重建进程,仅改文件不重建不生效。
Q3:渲染偶发 500 Timeout ... exceeded?
BROWSER_TIMEOUT 低于目标站点加载耗时波动区间(实测 2000ms 时同站点约半数请求超时)。按 P95 耗时放宽该值。
Q4:缓存目录增长失控?
filesystem 后端无自动清理,且 forceReload 在 v2.1.4 会产生新缓存文件(行为细节见 D5 篇 5.8 节)。对策:巡检 du -sh + 定期清目录(服务不停可直接 rm -f .../images/*.png),或升级到 main 之后已修复的版本。
Q5:/metrics 是 404?
METRICS 未开启。该变量默认 false,需要显式 METRICS: "true" 并重建。