配置
引导配置(环境变量)与运营配置(后台设置)的全部配置项、默认值、取值范围与生效方式,以及主密钥的保管。
两类配置
ImgYoung 的配置只分两类,没有配置文件,命令行参数只有 -version(打印版本、提交与构建时刻后退出)。
| 引导配置 | 运营配置 | |
|---|---|---|
| 内容 | 进程启动前就必须知道的:监听地址、数据目录、主密钥、信任的反代、指标放行网段 | 其余全部运营参数 |
| 来源 | 只认环境变量 IMGYOUNG_* | 元数据库里的 settings 表,不接受环境变量 |
| 修改 | 改环境变量后重启进程 | 后台「设置」修改,保存即生效,无需重启 |
| 查看 | 后台「设置 → 运行配置」底部的「引导配置」卡片(只读) | 后台「设置」 |
这样划分是为了让「这个值从哪来」永远只有一个答案:环境变量只负责把进程启动起来,其中有的还决定信任边界;运营配置只有后台一个写入方,不接受环境变量播种,也没有配置文件。
运营配置随元数据库持久化,也随元数据库快照一起备份与恢复。新实例在后台配置一次即可;升级新增的配置项由数据库迁移以出厂默认值补齐。
引导配置
| 环境变量 | 默认 | 格式 | 作用 |
|---|---|---|---|
IMGYOUNG_LISTEN | :8721 | host:port,如 127.0.0.1:8721、[::1]:8721;端口为 0 时由系统分配 | HTTP 监听地址。ImgYoung 只提供明文 HTTP,HTTPS 由前置反向代理负责 |
IMGYOUNG_DATA_DIR | data(相对进程工作目录) | 目录路径;不存在时以 0750 权限创建 | 数据目录:元数据库 imgyoung.db、主密钥文件 master.key、内置 local 渠道的 blobs/、衍生图缓存 variants/ |
IMGYOUNG_MASTER_KEY | 空(使用数据目录下的 master.key) | 64 个十六进制字符(32 字节) | 主密钥。每次启动与库里记下的主密钥指纹核对,缺失或不符即拒绝启动,见下文主密钥 |
IMGYOUNG_TRUSTED_PROXIES | 127.0.0.0/8,::1/128 | 逗号分隔的 CIDR 或单个 IP;单个 IP 视为只含该地址的网段 | 连接对端落在这些网段时才采信 X-Forwarded-For / X-Forwarded-Proto / X-Forwarded-Host,见反向代理与 HTTPS |
IMGYOUNG_METRICS_ALLOW | 127.0.0.0/8,::1/128,10.0.0.0/8,172.16.0.0/12,192.168.0.0/16,fc00::/7 | 同上 | 客户端地址落在这些网段时才放行 /metrics,其余一律 403,见监控与告警 |
-
变量未设置时取默认值;设为空串(或只有空白)就是显式置空。各变量的值都会去掉首尾空白。空值的含义:
IMGYOUNG_TRUSTED_PROXIES为空:一概不信转发头;IMGYOUNG_METRICS_ALLOW为空:/metrics对谁都不开放,一律 403;IMGYOUNG_MASTER_KEY为空:与未设置相同,使用数据目录下的master.key;IMGYOUNG_LISTEN、IMGYOUNG_DATA_DIR不接受空值,设为空串即启动失败,错误信息指出变量名。Compose 文件里写${VAR}而宿主机没有设置该变量时,容器拿到的就是空串;要用默认值,就不要设置这个变量。
后台「引导配置」卡片对空的网段清单显示「空:不采信任何转发头」「空:不对任何地址开放」。
-
两个网段清单在启动时解析,任一项既不是 CIDR 也不是 IP 时启动失败,错误信息给出变量名与出错的条目。监听地址在绑定端口时校验,主密钥在解析时校验,非法同样启动失败。
-
Docker 镜像已设置
IMGYOUNG_DATA_DIR=/data;deploy/imgyoung.service把它设为/var/lib/imgyoung。
各部署方式设置环境变量的位置:
IMGYOUNG_LISTEN=127.0.0.1:8721 IMGYOUNG_DATA_DIR=/srv/imgyoung ./imgyoung运营配置
运营配置在后台「设置」页修改,只有管理员可见。除「空 Referer 放行」在「防盗链」页签外,其余都在「运行配置」页签,按下列分组排列。
- 保存时只提交改动过的项;整组改动一起校验,任一项非法则全部不生效并提示原因。
- 生效即时:各后台循环的间隔改动后立刻按新值重新计时,不必等旧周期走完。
- 每次实际生效的修改记一条审计日志(动作
config.update,含新旧值),Cloudflare API Token 只记「已配置 / 空」。 - 同样的操作可经
GET /api/admin/config/full与PUT /api/admin/config完成,请求体为「配置键 → 新值」的 JSON 对象,见接口参考。 - 时长类配置项统一以 100 年(876000 小时)为上限,按各自单位折算:天 36500、小时 876000、分钟 52,560,000、秒 3,153,600,000、 毫秒 3,153,600,000,000,超出即拒绝保存。下表「取值」一栏对这些项只写下限。
下表的「默认」即出厂值,「取值」即服务端校验的范围。
访问与链接
| 配置键 | 界面名称 | 默认 | 取值 | 说明 |
|---|---|---|---|---|
access_mode | 访问模式 | proxy | proxy / redirect | proxy:图片由本服务从渠道读出后输出,渠道读取失败即时换下一个渠道。redirect:原图请求 302 到允许直链的渠道,重定向带 Cache-Control: no-store,见 CDN |
base_url | 对外站点地址 | 空 | 带协议的站点根地址,如 https://img.example.com;保存时去掉末尾的 / | 空则按请求推导。经 CDN 或反代后对外域名与请求域名不一致、启用 CDN 缓存清除、网盘渠道一键授权时必须设置,见反向代理与 HTTPS |
min_success | 最少同步副本 | 1 | ≥ 1 | 上传返回成功前必须同步写入的渠道数;健康渠道写不够这么多份时上传失败(503) |
encrypt_new_channels | 新渠道默认加密 | 关 | 开 / 关 | 新建渠道未显式选择时是否加密;加密属性在渠道创建时确定,之后不可改 |
上传限制
| 配置键 | 界面名称 | 默认 | 取值 | 说明 |
|---|---|---|---|---|
max_upload_mb | 单图上限 | 50 | ≥ 1,MB(1 MB = 1024 × 1024 字节) | 只约束图片本身,恰好等于上限的文件可以上传,超出返回 413;multipart 请求体整体另以「单图上限 + 64 KiB」为界。同时是 URL 转存与 S3 上传的大小上限,也是按需处理读取源图的上限:调小后,超过新上限的旧图做缩放或转格式时会回退原图 |
max_pixels_mp | 像素预算 | 50 | ≥ 1,百万像素 | 宽 × 高超过 max_pixels_mp × 1,000,000 的图片拒收(422) |
max_concurrent_uploads | 上传并发上限 | 8 | ≥ 1 | 全局共享:数据面上传、URL 转存、后台上传与 S3 协议面的全部请求共用一个上限;满载立即返回 429(Retry-After: 1) |
upload_rate_per_min | 上传频率上限 | 0 | ≥ 0,次 / 分钟 | 按用户计,同一用户经 Token 与后台上传共享额度,突发额度等于每分钟额度;超出返回 429(Retry-After: 60)。0 不限制 |
生命周期
| 配置键 | 界面名称 | 默认 | 取值 | 说明 |
|---|---|---|---|---|
default_ttl_hours | 默认有效期 | 0 | ≥ 0,小时 | 上传未指定 ttl、用户也没有自己的默认有效期时使用。0 永不过期 |
ttl_renew_on_access | 访问即续期 | 开 | 开 / 关 | 带有效期、尚未到期的图片被公开访问(GET)时,到期时刻顺延为访问落库时刻加其有效时长。已过到期时刻的图片立即不可访问,也不再续期 |
cold_cleanup_days | 冷图清理阈值 | 90 | ≥ 0,天 | 超过该天数未被公开访问的图片进入「待清理」等待人工裁决,不会自动删除。0 不标记 |
delete_grace_minutes | 删除宽限 | 0 | ≥ 0,分钟 | 物理图引用归零到删除渠道对象之间的等待。删除时刻在引用归零那一刻按当时的取值排定,之后修改不影响已排定的。0 表示下一轮清理扫描即删除 |
cleanup_sweep_seconds | 清理扫描间隔 | 60 | ≥ 1,秒 | 到期回收、物理删除、冷图标记、幂等键与审计日志回收的执行节奏 |
activity_flush_seconds | 活跃度落库间隔 | 60 | ≥ 1,秒 | 访问次数、最近访问时刻与衍生图缓存访问时间批量写库的间隔 |
idempotency_key_ttl_hours | 幂等键保留期 | 24 | ≥ 1,小时 | 带 Idempotency-Key 的上传重试在此期限内返回首次结果,超期的键被回收 |
按需处理
| 配置键 | 界面名称 | 默认 | 取值 | 说明 |
|---|---|---|---|---|
process_widths | 宽度档 | [100,200,400,800,1600] | 正整数数组,像素;可为空 | ?w= 只接受这些值,其余返回 400;为空时不允许缩放 |
process_formats | 目标格式 | ["webp","jpeg","png"] | webp、jpeg、png 的非空子集 | ?format= 只接受这些值。包含 webp 时,支持 WebP 的浏览器访问 JPEG / PNG 会自动得到 WebP |
exif_policy | EXIF 默认档 | passthrough | passthrough(保留)/ strip(剥离元数据) | 上传时的默认 EXIF 处理;单次上传可用表单字段 exif_policy 覆盖;S3 上传不适用,一律按原字节保存 |
process_quality_webp | WebP 质量档 | 80 | 0–100 | |
process_quality_jpeg | JPEG 质量档 | 85 | 1–100 | |
process_webp_method | WebP 速度权衡 | 4 | 0–6 | 越大编码越慢、体积越小 |
process_workers | 处理并发上限 | 4 | ≥ 1 | 同时进行的处理数;排队等待也计入处理超时 |
process_timeout_ms | 处理超时 | 5000 | ≥ 1,毫秒 | 含排队时间;超时回退原图,该响应带 Cache-Control: no-store |
variants_cache_mb | 衍生图缓存上限 | 10240 | ≥ 1,MB | 衍生图缓存在 <数据目录>/variants/,超出按最近访问时间淘汰 |
查重
| 配置键 | 界面名称 | 默认 | 取值 | 说明 |
|---|---|---|---|---|
dedup_scan_seconds | 查重扫描间隔 | 300 | ≥ 1,秒 | 每轮先自动合并内容完全相同的图片,再做相似扫描 |
dedup_phash_max_distance | 相似判定阈值 | 10 | ≥ 0,汉明距离 | 感知哈希距离不超过该值的图片进入「疑似重复」等待人工裁决。0 不做相似扫描,完全相同的图片仍自动合并 |
可靠性与渠道
| 配置键 | 界面名称 | 默认 | 取值 | 说明 |
|---|---|---|---|---|
health_check_seconds | 健康检查间隔 | 60 | ≥ 1,秒 | 渠道健康探测与告警评估的节奏 |
backup_interval_hours | 备份间隔 | 24 | ≥ 1,小时 | 元数据库自动快照的间隔。启动时任一健康渠道上缺少这个间隔内的快照,就先备份一次。见备份与恢复 |
backup_keep | 备份保留份数 | 7 | ≥ 1 | 快照写到每个健康且不在清理中的渠道;每个渠道写入后各自只保留最新的这么多份 |
usage_report_seconds | 用量上报间隔 | 300 | ≥ 1,秒 | 只决定指标 imgyoung_channel_storage_bytes 的刷新节奏;用量告警按健康检查间隔评估 |
channel_quota_gb | 渠道用量告警阈值 | 0 | ≥ 0,GB(1 GB = 2³⁰ 字节) | 任一渠道已存数据(按已就绪副本的图片大小求和)超过阈值即开启告警,不限制写入。0 不告警 |
CDN 缓存清理
| 配置键 | 界面名称 | 默认 | 取值 | 说明 |
|---|---|---|---|---|
cdn_cloudflare_zone_id | Cloudflare Zone ID | 空 | 文本 | |
cdn_cloudflare_api_token | Cloudflare API Token | 空 | 文本 | 需要 Cache Purge 权限。以主密钥加密后入库,任何接口、页面与日志都不回显。表单留空表示不修改,用「清除 Token」清空 |
Zone ID、API Token 与 base_url 三项齐备才启用缓存清除,分组标题旁的徽标显示「purge 已启用 / purge 未启用」,启动日志也会打印一行启用状态。详见 CDN。
告警与审计
| 配置键 | 界面名称 | 默认 | 取值 | 说明 |
|---|---|---|---|---|
alert_webhook_url | 告警 Webhook 地址 | 空 | 空,或带主机的 http / https 地址 | 告警开启与恢复时 POST 一条 JSON,负载格式见监控与告警。空则只记录不外发 |
audit_retention_days | 审计日志保留天数 | 0 | ≥ 0,天 | 清理扫描时删除早于该天数的审计记录。0 永久保留 |
防盗链页签
| 配置键 | 界面名称 | 默认 | 取值 | 说明 |
|---|---|---|---|---|
allow_empty_referer | 空 Referer 放行 | 开 | 开 / 关 | Referer 白名单非空时,不带 Referer 的请求(地址栏直接打开、下载工具)是否放行。白名单为空时防盗链整体不启用,本项不起作用 |
白名单规则本身在同一页签增删,不属于 settings 表。
主密钥
主密钥是 32 字节的随机数,用于:
- 加密渠道配置(含各渠道的凭证)与 Cloudflare API Token 后入库;
- 为每个加密渠道派生 crypt 密码与盐;
- 为每枚上传 Token 派生 S3 协议面的 secret(不落库,按需重算)。
上传 Token 与登录密码只存哈希,不依赖主密钥。
生成与核对
启动时按以下顺序取得主密钥:IMGYOUNG_MASTER_KEY 非空时用它,不读也不生成 master.key;否则读数据目录下的 master.key。
取得之后与库里记下的主密钥指纹核对。指纹存在单行表 master_key_fingerprint 里,由主密钥经 HKDF-SHA256 派生,不能反推出主密钥。
- 库里还没有指纹(全新的库,或从未记录过指纹的库):主密钥两处都没有时,在数据目录生成
master.key(64 个十六进制字符加换行,权限0600,先写临时文件再改名)并打印一条警告日志提醒备份;随后把这把主密钥的指纹写进库里。 - 库里已有指纹:主密钥必须存在且与指纹相符。
IMGYOUNG_MASTER_KEY未设置或为空、数据目录下也没有master.key, 或者主密钥与指纹不符,一律拒绝启动并说明原因,不会生成新密钥。只有全新的库才会生成master.key。 master.key存在但内容不是合法的 64 位十六进制时启动失败,不会重新生成:重新生成会让所有已有密文作废。
想自己生成一把主密钥:
openssl rand -hex 32从文件方式改用环境变量时,把 master.key 的内容原样填进变量;填错时指纹核对不通过,进程拒绝启动。
保管
主密钥不在元数据库快照里,也不在元数据导出里,必须单独备份到与服务器、快照都不同的地方。首次启动后立即复制一份:
cp data/master.key /安全位置/imgyoung-master.key丢失或换错的后果
主密钥不支持更换。库里记下指纹之后,换错与缺失都会在启动时被拦下:
- 用了另一把主密钥(例如
IMGYOUNG_MASTER_KEY填错):拒绝启动,错误信息提示换回原来的主密钥;换回后照常启动。 - 主密钥缺失(例如数据目录里的
master.key被删,或 Compose 里的${VAR}在宿主机上没有设置):拒绝启动,不会生成新密钥; 放回原来的主密钥后照常启动。
主密钥真正丢失时无法挽回,这个库无法再启动,用它加密的数据都救不回来:
- 渠道配置(含各渠道的凭证)无法解密;
- 加密渠道上的数据(含存放在加密渠道上的元数据库快照)永久无法解密;
- Cloudflare API Token 无法解密;
- 全部上传 Token 的 S3 secret 无法再算出。
先备份 master.key
元数据库快照、数据导出和渠道里的图片都救不回丢失的主密钥。灾难恢复时,新机器必须在首次启动前放入同一个主密钥; 恢复别的实例的快照后,要换上那个实例的主密钥,否则指纹不符、拒绝启动。见备份与恢复。