Shlink 5.1.8 配置参数详解
Shlink 5.1.8 配置参数详解:67 项环境变量全清单分组总览、四级加载机制与 _FILE secret 注入,域名/短码/数据库/跳转/统计/缓存/删除保护九大维度逐项实测。
Shlink 5.1.8 配置参数详解
本文基于 shlinkio/shlink 5.1.8 实测(2026-10-30,四组单容器实验栈逐项验证配置项行为,全部命令与回显均为真实运行结果;配置项清单与默认值溯源自 v5.1.8 源码
module/Core/src/Config/EnvVars.php)。
一、环境信息与实验说明
- 服务版本:
shlinkio/shlink:5.1.8(REST 健康端点实测返回"version":"5.1.8"); - 实验形态:四组 SQLite 单容器实例(免数据库依赖,最快暴露配置行为),另起一个
redis:7容器专测 Redis 缓存配置; - 端口规划:
8136/8137/8138/8139分别对应 A/B/C/D 四组实验实例(宿主常用端口已被占用时的高位映射做法同系列部署篇); - 取证口径:应用层环境变量全集从 v5.1.8 源码
EnvVars枚举逐项核对(67 项),另含 RoadRunner 运行时层 5 项与 Docker 镜像层内置变量;行为语义以「源码定义 + 实测回显」双重印证。
二、配置加载机制与查看方式
2.1 四级加载优先级
Shlink 5.1.8 的配置加载逻辑(源码 EnvVars::loadFromEnv())按以下顺序取值,前者命中即止:
- 环境变量:容器
-e/ Composeenvironment:注入,最高优先级; <变量名>_FILEsecret 文件:任意配置项都支持追加_FILE后缀(如DB_PASSWORD_FILE=/run/secrets/db_pass),Shlink 读取文件内容作为该变量的值——这是官方为 Docker secrets 场景设计的通道,数据库口令等敏感项建议走此路,避免明文出现在编排文件;- 交互安装器落盘值:宿主机直装时
shlink-installer init把应答写入本地配置文件,容器形态下 entrypoint 以--no-interaction执行安装器,主要消费默认值与环境变量; - 内置默认值:
EnvVars::defaultValue()硬编码,如DB_DRIVER默认sqlite、MEMORY_LIMIT默认512M、TRACK_ORPHAN_VISITS默认true、CORS_ALLOW_ORIGIN默认*、CORS_MAX_AGE默认3600、LOGS_FORMAT默认console、CACHE_NAMESPACE默认Shlink。
两个与数据库端口相关的联动默认值值得注意:DB_DRIVER=postgres 时 DB_PORT 默认 5432,mssql 时默认 1433,其余驱动默认 3306;DB_HOST 未设置时回落取 DB_UNIX_SOCKET(Unix socket 连接场景)。
2.2 查看与修改方式
读取某个生效值(entrypoint 内部也是用它做启动分支判断的):
$ docker exec shlink-cfg-a shlink env-var:read DEFAULT_SHORT_CODES_LENGTH
8
未设置的变量读取结果为空(实测未设 GEOLITE_LICENSE_KEY 的 D 组实例返回空行)。修改方式只有一种:改环境变量后重建容器(Compose 下改 environment: 后 docker compose up -d 会自动重建),Shlink 无配置热更新,短链数据在数据库/数据卷中不受重建影响。
💡 技术拓展:12-Factor 应用的「配置进环境变量」原则把配置与代码彻底分离,Shlink 是 PHP 服务里执行得最彻底的一类——全部 67 项应用配置无一落配置文件,这让 secrets 文件、Compose 变量替换、kubectl env 等通道都能直接复用;代价是配置校验延迟到启动时(如 Redis 地址写错要等启动日志报错)。传统 PHP 应用常用的
config.php静态文件模式则相反,改文件即生效但难进版本管理与密钥管理。两者取舍上,容器化部署场景环境变量模式优势明显。
三、参数总览(67 项应用配置分组)
以下分组清单与 v5.1.8 源码 EnvVars 枚举一一对应,共 67 项;加粗为本文有实测的项。
| 分组 | 变量 | 默认值 | 说明 |
|---|---|---|---|
| 域名与访问 | DEFAULT_DOMAIN | 空 | 生成短链的默认域名(可含端口),容器形态下必配 |
| 域名与访问 | IS_HTTPS_ENABLED | true | 短链是否以 https:// 输出 |
| 域名与访问 | BASE_PATH | 空 | 子路径部署前缀(如 /s) |
| 域名与访问 | TIMEZONE | 服务器时区 | 影响统计时间戳 |
| 域名与访问 | SHORT_URL_TRAILING_SLASH | false | 访问侧允许短码带尾斜杠命中 |
| 域名与访问 | SHORT_URL_MODE | strict | 短码大小写策略:strict/loose |
| 域名与访问 | MULTI_SEGMENT_SLUGS_ENABLED | false | 自定义短码允许多段斜杠 |
| 域名与访问 | REDIRECT_EXTRA_PATH_MODE | default | 短码后附加路径处理:default/append/ignore |
| 域名与访问 | AUTO_RESOLVE_TITLES | true | 创建时自动抓取目标页标题 |
| 短码 | DEFAULT_SHORT_CODES_LENGTH | 5 | 随机短码长度(最小 4) |
| 数据库 | DB_DRIVER | sqlite | sqlite/postgres/mysql/mssql |
| 数据库 | DB_NAME | shlink | 库名 |
| 数据库 | DB_USER / DB_PASSWORD | 空 | 认证三元组 |
| 数据库 | DB_HOST / DB_PORT | 按驱动回落 | 主机与端口(端口随驱动默认) |
| 数据库 | DB_UNIX_SOCKET | 空 | Unix socket 连接 |
| 数据库 | DB_USE_ENCRYPTION | false | MSSQL 加密连接 |
| 跳转行为 | REDIRECT_STATUS_CODE | 302 | 301/302/307/308 |
| 跳转行为 | DEFAULT_INVALID_SHORT_URL_REDIRECT | 空 | 无效短码兜底跳转(空=404) |
| 跳转行为 | DEFAULT_REGULAR_404_REDIRECT | 空 | 常规 404 兜底跳转 |
| 跳转行为 | DEFAULT_BASE_URL_REDIRECT | 空 | 访问域名根路径兜底跳转 |
| 跳转行为 | REDIRECT_CACHE_LIFETIME | 30 | 跳转缓存 TTL(秒) |
| 跳转行为 | REDIRECT_CACHE_VISIBILITY | private | 缓存响应头 public/private |
| 统计与隐私 | TRACK_ORPHAN_VISITS | true | 记录孤儿访问 |
| 统计与隐私 | DISABLE_TRACK_PARAM | 空 | 带此 query 参数的访问不计数 |
| 统计与隐私 | DISABLE_TRACKING | false | 全局关闭统计 |
| 统计与隐私 | DISABLE_IP_TRACKING | false | 不记录 IP 与地理 |
| 统计与隐私 | DISABLE_REFERRER_TRACKING | false | 不记录来源页 |
| 统计与隐私 | DISABLE_UA_TRACKING | false | 不记录 User-Agent |
| 统计与隐私 | ANONYMIZE_REMOTE_ADDR | true | IP 落库前匿名化 |
| 统计与隐私 | DISABLE_TRACKING_FROM | 空 | 按 IP/网段关闭统计(逗号分隔) |
| 缓存 | REDIS_SERVERS | 空 | Redis 地址(tcp://host:port,逗号分隔多台) |
| 缓存 | REDIS_SENTINEL_SERVICE | 空 | Sentinel 服务名 |
| 缓存 | REDIS_SERVERS_USER / REDIS_SERVERS_PASSWORD | 空 | Redis 认证 |
| 缓存 | REDIS_PUB_SUB_ENABLED | false | 启用 Redis 发布订阅(多实例实时更新) |
| 缓存 | CACHE_NAMESPACE | Shlink | 缓存键命名空间 |
| 实时更新 | MERCURE_ENABLED | 设了公共 Hub 即启用 | Mercure 推送开关 |
| 实时更新 | MERCURE_PUBLIC_HUB_URL / MERCURE_INTERNAL_HUB_URL | 空 | 公共/内部 Hub 地址 |
| 实时更新 | MERCURE_JWT_SECRET | 空 | Hub 签名密钥 |
| 实时更新 | REAL_TIME_UPDATES_TOPICS | 空 | 推送主题过滤 |
| 消息队列 | RABBITMQ_ENABLED | false | 启用 RabbitMQ 实时更新 |
| 消息队列 | RABBITMQ_HOST / RABBITMQ_PORT | 空 / 5672 | 地址端口 |
| 消息队列 | RABBITMQ_USER / RABBITMQ_PASSWORD / RABBITMQ_VHOST | 空 / 空 / / | 认证与虚拟主机 |
| 消息队列 | RABBITMQ_USE_SSL | false | SSL 连接 |
| 集成 | MATOMO_ENABLED | false | 推送访问到 Matomo |
| 集成 | MATOMO_BASE_URL / MATOMO_SITE_ID / MATOMO_API_TOKEN | 空 | Matomo 对接三件套 |
| GeoIP | GEOLITE_LICENSE_KEY | 空 | GeoLite2 许可证 Key |
| GeoIP | SKIP_INITIAL_GEOLITE_DOWNLOAD | false | 跳过启动时下载 |
| API | INITIAL_API_KEY | 空 | 首次启动预置 API Key |
| 删除保护 | DELETE_SHORT_URL_THRESHOLD | 15 | 访问数达到阈值的短链删除需确认 |
| Robots | ROBOTS_ALLOW_ALL_SHORT_URLS | false | 允许爬虫收录短链 |
| Robots | ROBOTS_USER_AGENTS | 空 | 自定义 robots UA 列表 |
| CORS | CORS_ALLOW_ORIGIN | * | REST API 跨域来源 |
| CORS | CORS_ALLOW_CREDENTIALS | false | 跨域携带凭据 |
| CORS | CORS_MAX_AGE | 3600 | 预检缓存秒数 |
| 运维杂项 | APP_ENV | prod | prod/dev/test |
| 运维杂项 | MEMORY_LIMIT | 512M | PHP 内存上限 |
| 运维杂项 | LOGS_FORMAT | console | 日志格式 |
| 运维杂项 | TRUSTED_PROXIES | 空 | 信任的反代 IP/网段(逗号分隔) |
除上表外,RoadRunner 运行时层还有 5 个变量直接作用于 .rr.yml 模板:PORT(监听端口,默认 8080,Docker 镜像 EXPOSE 8080 与映射目标一致)、ADDRESS(监听地址,默认 0.0.0.0)、WEB_WORKER_NUM(HTTP worker 数,默认 0=自动按 CPU)、TASK_WORKER_NUM(任务 worker 数)、LOGS_FORMAT(与应用层同名共用)。日常部署只需关注 PORT,容器场景端口映射的宿主侧才是常改的那一端。
四、域名与访问参数详解
4.1 DEFAULT_DOMAIN 与 IS_HTTPS_ENABLED(必配项)
DEFAULT_DOMAIN 决定生成短链的域名部分,官方 Docker 镜像把它列为必配三项之一。它只影响生成侧,不影响跳转侧——跳转统计记录的是真实请求 Host(这个错位行为在系列 FAQ 篇 Q1 有完整复盘)。IS_HTTPS_ENABLED 决定生成短链的 scheme,置于反代之后做 TLS 终结时应改为 true。
实测:A 组实例设 DEFAULT_DOMAIN=surl-cfga.localhost:8136 + IS_HTTPS_ENABLED=false,生成的短链严格按这两个值拼接:
$ docker exec shlink-cfg-a shlink short-url:create -n https://www.quzuo.net/
Processed long URL: https://www.quzuo.net/
Generated short URL: http://surl-cfga.localhost:8136/QCOMq3md
-n 是跳过长 URL 可达性检查(离线环境创建短链必备,参数详解见 《Shlink 5.1.8 REST API 与 CLI 命令详解》)。
4.2 SHORT_URL_TRAILING_SLASH(访问侧语义,易误解项)
这是 5.x 里最容易误解的配置:它不改变生成结果(生成侧源码 ShortUrlStringifier 固定输出 scheme://domain/code,无尾斜杠分支),真正的语义在访问匹配侧——启用后,短码路径尾部多出的 / 会被中间件裁掉再匹配短码。
两组对比实测(A 组 SHORT_URL_TRAILING_SLASH=true,B 组默认 false):
# B 组(默认 false):带尾斜杠访问直接 404
$ curl -s -o /dev/null -w 'HTTP %{http_code}\n' http://localhost:8137/jmAHb/
HTTP 404
# A 组(true):带尾斜杠访问正常跳转
$ curl -s -o /dev/null -w 'HTTP %{http_code} -> %{redirect_url}\n' http://localhost:8136/QCOMq3md/
HTTP 302 -> https://www.quzuo.net/
结论:短链一旦对外发布(印刷物料、公众号文章等场景用户可能手滑带上尾斜杠),把该项设为 true 是零成本的容错;纯线上分享场景保持默认即可。
4.3 TIMEZONE 与统计时间戳
TIMEZONE 未设置时回落服务器时区(容器内默认 UTC)。对照实测:未设该变量的 C 组实例,访问记录时间为 2026-10-30T06:52:59+00:00;系列部署篇设 TIMEZONE=Asia/Shanghai 后同样操作记录为 +08:00 时区。做统计报表按天聚合时,这个变量决定「一天」的边界,国内业务建议显式设为 Asia/Shanghai。
4.4 其余访问类参数
BASE_PATH:子路径部署(如挂在https://example.com/s/下)时设前缀,短链与 REST API 路径都会加上前缀;独立域名部署保持默认空值;SHORT_URL_MODE=loose:短码改为大小写不敏感匹配(随机短码字符集同时缩为纯小写数字,见 5.2),适合短码会被口头转述、电话下单等大小写易混场景;MULTI_SEGMENT_SLUGS_ENABLED=true:自定义短码允许带斜杠(如campaign/2026/q4),把短链当路径聚合页用;REDIRECT_EXTRA_PATH_MODE:控制短码后附加路径的语义——default附加路径不匹配短链(当 404 处理)、append把附加路径拼到目标长 URL 后(适合把短链当目录前缀跳转到文档深层页面)、ignore忽略附加路径照常跳转;AUTO_RESOLVE_TITLES=false:关闭创建时自动抓取目标页标题(内网目标地址抓取会拖慢创建速度时关掉)。
五、短码生成参数详解
5.1 DEFAULT_SHORT_CODES_LENGTH(实测 8 位)
随机短码长度,默认 5,源码硬编码下限 MIN_SHORT_CODES_LENGTH = 4(设更小值按 4 处理)。A 组实测设 8:
$ docker exec shlink-cfg-a shlink short-url:create -n https://shlink.io
Processed long URL: https://shlink.io
Generated short URL: http://surl-cfga.localhost:8136/dwYfJKTl
生成码 dwYfJKTl 恰为 8 位,且第二组对照 QCOMq3md 同样 8 位——长度稳定生效。对照 B 组(未设置,默认 5)生成 jmAHb。
长度选择上有明确的量化依据:默认字符集 62 个字符(大小写字母+数字),5 位码理论空间 62⁵ ≈ 9.16 亿,对绝大多数自托管场景绰绰有余;调大到 8 位(62⁸ ≈ 2.18 万亿)只在两类场景有意义——防短码枚举爬虫、或对短码随机性有合规要求。代价仅是短链多 3 个字符。
5.2 短码字符集(版本差异,5.x 不可配)
注意版本差异:旧版 Shlink 提供 SHORT_CODE_CHARS 环境变量自定义字符集,5.1.8 已移除该变量(源码 EnvVars 枚举中不存在)。现在字符集由 SHORT_URL_MODE 决定,写死在源码里:
| 模式 | 字符集 | 说明 |
|---|---|---|
strict(默认) | 0-9a-zA-Z(62 字符) | 大小写敏感 |
loose | 0-9a-z(36 字符) | 大小写不敏感匹配,生成也只用小写 |
5.3 自定义短码的约束
自定义 slug(customSlug 参数或 CLI --custom-slug)不受 DEFAULT_SHORT_CODES_LENGTH 约束,可长可短;启用 MULTI_SEGMENT_SLUGS_ENABLED 后可含斜杠。冲突时 REST API 返回 400,加 findIfExists: true 改为复用既有短链(实测细节见系列 API 篇)。
六、数据库参数详解
6.1 驱动选择与连接三元组
DB_DRIVER 默认 sqlite(零依赖起步,数据文件在容器内 /etc/shlink/data/database.sqlite),可选 postgres/mysql/mssql。生产推荐 PostgreSQL 或 MySQL,驱动与端口默认值联动(postgres→5432、mssql→1433、mysql→3306),库内网标准端口时 DB_PORT 可省略。
连接 postgres 驱动的完整配置(实测可用形态,与系列部署篇一致):
environment:
DB_DRIVER: "postgres"
DB_HOST: "shlink-db" # compose 服务名
DB_PORT: "5432"
DB_NAME: "shlink"
DB_USER: "shlink"
DB_PASSWORD: "q1w2E3r4"
DB_HOST不设时回落 Unix socket(DB_UNIX_SOCKET),适合同宿主机直装形态;DB_USE_ENCRYPTION=true仅对 MSSQL 有意义(驱动层加密连接);- 敏感项走 secret 文件:
DB_PASSWORD_FILE=/run/secrets/shlink_db_pass,Shlink 读文件内容作口令,编排文件与进程列表均不再出现明文。
6.2 形态取舍
SQLite 只适合个人低流量(并发写入能力弱、统计查询慢),且数据必须挂卷持久化;PostgreSQL 形态的编排、健康检查与备份链路已在 《Shlink 5.1.8 Docker Compose 部署指南》 全量实测。数据层日常操作命令可参照 《PostgreSQL 18 常用 CLI 命令与工具详解》。
七、跳转行为参数详解
7.1 REDIRECT_STATUS_CODE(实测 301)
跳转状态码,可选 301/302/307/308,默认 302。C 组实测设 301:
$ curl -s -o /dev/null -w 'HTTP %{http_code} -> %{redirect_url}\n' http://localhost:8138/RO7Vl
HTTP 301 -> https://www.quzuo.net/
选型依据:302(默认)表示临时跳转,浏览器不缓存,每次点击都会回到 Shlink 记录统计,依赖统计的场景保持默认;301 永久跳转,浏览器与中间代理会缓存跳转结果,后续点击可能不再经过 Shlink(统计缩水),仅适合确定不再变更目标且不追求统计的短链;307/308 保留原请求方法,用于把短链指到 POST 接口(如把支付回调地址变短)。注意该值是全局的,下一节的兜底跳转也会沿用。
7.2 三个 404 场景兜底跳转
三个变量分别接管三类「没找到」流量,未设置时一律 404:
| 变量 | 接管场景 | 典型用法 |
|---|---|---|
DEFAULT_INVALID_SHORT_URL_REDIRECT | 短码不存在/已失效 | 把失效短链导流到活动页或首页,挽回流量 |
DEFAULT_REGULAR_404_REDIRECT | 不匹配任何短链规则的普通 404 | 导流到站点首页 |
DEFAULT_BASE_URL_REDIRECT | 直接访问短链域名根路径 | 把裸短域名导流到品牌页 |
C 组实测 DEFAULT_INVALID_SHORT_URL_REDIRECT=https://www.quzuo.net/:访问不存在的短码不再 404,而是按全局状态码跳转:
$ curl -s -o /dev/null -w 'HTTP %{http_code} -> %{redirect_url}\n' http://localhost:8138/no-such-code
HTTP 301 -> https://www.quzuo.net/
对照系列 API 篇默认行为(未设兜底时 GET /no-such-code 返回 404 并记入 orphan visits)。
7.3 跳转缓存
REDIRECT_CACHE_LIFETIME(默认 30 秒)+ REDIRECT_CACHE_VISIBILITY(默认 private)控制跳转响应的浏览器缓存头。调大 TTL 可减少重复点击回源,但同样以统计精度为代价;private 限制仅浏览器缓存,public 允许中间 CDN 缓存(流量大且不依赖统计时可开)。
八、统计与隐私参数详解
8.1 TRACK_ORPHAN_VISITS(实测关闭)
孤儿访问指不对应任何短链的流量:失效短码访问、根路径访问等。默认 true 记录。C 组实测 TRACK_ORPHAN_VISITS=false 后,访问不存在的短码再查孤儿列表,表为空(仅表头):
$ docker exec shlink-cfg-c shlink visit:orphan --no-ansi
+------+---------------+------------+---------+---------+--------+------+-------------+--------------+------+
| Date | Potential bot | User agent | Referer | Country | Region | City | Visited URL | Redirect URL | Type |
+------+---------------+------------+---------+- Page 1 of 1 ----+------+-------------+--------------+------+
配合 7.2 的兜底跳转使用是合理组合——失效流量已被导流,孤儿统计的意义只剩排障。爬虫扫描带来的海量无效访问撑大 visit 表时,关掉它可显著抑制表膨胀。
8.2 DISABLE_TRACK_PARAM(实测 ?myp=1 不计数)
设置一个魔法 query 参数名后,任何带该参数的访问不计入统计。C 组实测 DISABLE_TRACK_PARAM=myp:
$ curl -s -o /dev/null http://localhost:8138/RO7Vl?myp=1 # 不产生记录
$ curl -s -o /dev/null http://localhost:8138/RO7Vl # 正常记录
$ docker exec shlink-cfg-c shlink short-url:visits RO7Vl --no-ansi
+---------------------------+---------------+-------------+---------+---------+---------+---------+-----------------------------+------------------------+-----------------+
| Date | Potential bot | User agent | Referer | Country | Region | City | Visited URL | Redirect URL | Type |
+---------------------------+---------------+-------------+---------+---------+---------+---------+-----------------------------+------------------------+-----------------+
| 2026-10-30T06:52:59+00:00 | Potential bot | curl/8.18.0 | | Unknown | Unknown | Unknown | http://localhost:8138/RO7Vl | https://www.quzuo.net/ | valid_short_url |
+---------------------------+---------------+-------------+---------+---------+---------+---------+-----------------------------+------------------------+-----------------+
带 ?myp=1 的那次访问没有出现在明细里,正常访问记录在案。用途:自己点击验证短链是否存活而不污染统计数据(替代系列 FAQ 篇 Q6 的「事后清理」法,前置规避优于事后删除)。
8.3 全局开关与细粒度开关
DISABLE_TRACKING=true:全局关闭统计(跳转照常,visit 表零写入),DISABLE_IP_TRACKING等一切统计开关均被它压制;DISABLE_IP_TRACKING=true:不记 IP 且不解析地理(地理位置库下载都可省);DISABLE_REFERRER_TRACKING/DISABLE_UA_TRACKING:分别不记来源页/User-Agent;ANONYMIZE_REMOTE_ADDR=true(默认):IP 落库前做匿名化(IPv4 末段置零、IPv6 截断),满足 GDPR 类合规要求,开启后地理定位精度降到城市级以内基本无影响;DISABLE_TRACKING_FROM:按 IP/网段关闭统计(逗号分隔,如192.168.1.0/24,10.0.0.5),办公网自测流量默认不计入,与 8.2 互补。
8.4 隐私配置的合规组合模板
面向欧盟用户的统计合规组合:ANONYMIZE_REMOTE_ADDR=true(保持默认)+ DISABLE_TRACKING_FROM=192.168.1.0/24(换成自家办公网段)+ 可选 DISABLE_UA_TRACKING=true。需要完全合规(不落任何个人数据)则直接 DISABLE_TRACKING=true,Shlink 退化为纯跳转服务。
九、缓存与实时更新参数详解
9.1 REDIS_SERVERS(实测 13 个缓存键)
未配置 Redis 时 Shlink 用进程内数组缓存(多实例不共享,重启即失)。配置后缓存与锁全部落到 Redis。D 组实测单机 Redis:
$ docker run -d --name shlink-cfg-redis --network shlink-cfg-net redis:7
$ docker run -d --name shlink-cfg-d --network shlink-cfg-net \
-p 8139:8080 \
-e DEFAULT_DOMAIN=surl-cfgd.localhost:8139 \
-e IS_HTTPS_ENABLED=false \
-e REDIS_SERVERS=tcp://shlink-cfg-redis:6379 \
shlinkio/shlink:5.1.8
创建短链并访问一次后,Redis 侧实测出现 13 个 Shlink: 前缀键:
$ docker exec shlink-cfg-redis redis-cli --scan --pattern 'Shlink*'
Shlink:Shlinkio__Shlink__Core__Tag__Entity__Tag__CLASSMETADATA__
Shlink:36c7821085bdac13c0673c86b8352f44
Shlink:Shlinkio__Shlink__Core__Visit__Entity__VisitLocation__CLASSMETADATA__
Shlink:Shlinkio__Shlink__Core__Visit__Entity__ShortUrlVisitsCount__CLASSMETADATA__
Shlink:Shlinkio__Shlink__Core__ShortUrl__Entity__ShortUrl__CLASSMETADATA__
Shlink:Shlinkio__Shlink__Core__RedirectRule__Entity__ShortUrlRedirectRule__CLASSMETADATA__
Shlink:fa82f3c2096b04dcdd680367626113da
Shlink:Shlinkio__Shlink__Core__Visit__Entity__Visit__CLASSMETADATA__
Shlink:Shlinkio__Shlink__Core__Domain__Entity__Domain__CLASSMETADATA__
Shlink:d45626bdc5c721eed382d31da5a4fc8d
Shlink:3d7d8aff9404de494dccab7bd9d0b070
Shlink:Shlinkio__Shlink__Rest__Entity__ApiKey__CLASSMETADATA__
Shlink:07754e78a13658f1aedd368cfd4d9176
两类键:CLASSMETADATA 结尾的是 Doctrine ORM 元数据缓存;哈希名的是短码→长 URL 的跳转缓存(受 7.3 的 TTL 控制)。地址格式 tcp://host:port,多实例间逗号分隔(如 tcp://r1:6379,tcp://r2:6379,客户端侧分片)。REDIS_SENTINEL_SERVICE 配 Sentinel 服务名接管地址发现;REDIS_SERVERS_USER/REDIS_SERVERS_PASSWORD 配 ACL 认证。
9.2 REDIS_PUB_SUB_ENABLED 与多实例实时更新
多实例部署时,A 实例建的短链 B 实例的跳转缓存要失效——默认靠缓存 TTL 自然过期(最长 30 秒不一致),设 REDIS_PUB_SUB_ENABLED=true 后改为 Redis 发布订阅即时广播失效事件。单实例无此需求,保持默认。
9.3 Mercure 与 RabbitMQ(可选实时面)
Shlink 的实时推送(Web Client 的访问实时刷新)有两条通道:MERCURE_*(Mercure Hub,SSE 协议)与 RABBITMQ_*(AMQP)。MERCURE_ENABLED 默认随 MERCURE_PUBLIC_HUB_URL 是否设置联动;两者同时启用时事件双发。REAL_TIME_UPDATES_TOPICS 过滤推送主题(如只要短链更新、不要访问事件)。自托管最小化部署建议两者都不开,实时面用 CLI/API 轮询替代。
十、GeoIP 与删除保护参数详解
10.1 GEOLITE_LICENSE_KEY(实测无 Key 报错)
地理定位依赖 MaxMind GeoLite2 离线库,Shlink 默认不带。容器启动时 entrypoint 检查 GEOLITE_LICENSE_KEY:有值则初始化阶段自动下载库文件,无值(或 SKIP_INITIAL_GEOLITE_DOWNLOAD=true)则跳过。未配置 Key 时手动下载实测报错:
$ docker exec shlink-cfg-d shlink visit:download-db
Downloading GeoLite2 db file...
[WARNING] It was not possible to download GeoLite2 db, because a license was
not provided.
exit=2
Key 在 MaxMind 免费注册获取。未配置时的直接后果:访问明细的 Country/Region/City 全为 Unknown(系列 API 篇实测留痕),补配 Key 后执行 visit:download-db 下载、visit:locate 回溯存量记录。GeoLite2 每周更新,库文件放 cron 定期刷新。
10.2 DELETE_SHORT_URL_THRESHOLD(实测删除保护)
防误删保护:访问次数达到阈值的短链,删除命令会被拦截。源码默认 15。B 组实测设 DELETE_SHORT_URL_THRESHOLD=2,访问 2 次后删除:
$ curl -s -o /dev/null http://localhost:8137/jmAHb # ×2 次访问
$ docker exec shlink-cfg-b shlink short-url:delete jmAHb
Impossible to delete short URL with short code "jmAHb", since it has more than "2" visits.
Do you want to delete it anyway? (yes/no) [no]:
>
[WARNING] Short URL was not deleted.
exit=2
三个实测细节:拦截时 CLI 给交互确认(默认 no,脚本场景无交互输入即退出码 2 不删);确认 yes 可强删;-i/--ignore-threshold 参数直接跳过检查(short-url:delete -i jmAHb)。对照实测 0 访问的短链删除畅通:
$ docker exec shlink-cfg-b shlink short-url:delete lGwu3
[OK] Short URL with short code "lGwu3" successfully deleted.
阈值语义是「访问数超过该值的短链删除需确认」:营销类高价值短链多的环境调大(如 100),测试环境调小(如 1)让保护尽早介入。
10.3 INITIAL_API_KEY
首次启动预置 API Key(UUID 形态),省掉容器起来后手动 shlink api-key:generate 一步,也便于基础设施即代码(编排文件里固定 Key,服务一就绪集成方即可调用)。已初始化的实例设置它无效果,Key 管理命令全集见 《Shlink 5.1.8 REST API 与 CLI 命令详解》。
十一、运维杂项参数详解
11.1 资源与运行时
MEMORY_LIMIT(默认512M):PHPmemory_limit,启动时经ini_set注入(源码container.php),统计量大、批量导入短链时按需调到1G;RoadRunner 常驻 worker 的重启阈值(处理 250 个请求后重建进程防内存泄漏)由镜像内置,不受此变量控制;LOGS_FORMAT:日志输出格式,默认console(人类可读),容器日志采集进 ELK/Loki 时改json;APP_ENV:prod(默认)/dev/test,dev 模式会输出详细错误栈,生产严禁;TRUSTED_PROXIES:Shlink 在反代之后必须配置信任网段(如10.89.0.0/16),否则统计里的客户端 IP 全是反代地址、地理定位随之失效;与X-Forwarded-For头处理直接相关。
11.2 REST API 跨域(CORS_*)
Web 前端直连 Shlink REST API 时才需要关注:CORS_ALLOW_ORIGIN 默认 *(开发方便但生产建议收敛到自家域名,如 https://admin.example.com)、CORS_ALLOW_CREDENTIALS 默认 false、CORS_MAX_AGE 默认 3600(预检请求缓存一小时)。纯服务端调用(curl/SDK)不受 CORS 影响。
11.3 Robots 与 Matomo 集成
ROBOTS_ALLOW_ALL_SHORT_URLS=true:默认 Shlink 对短链返回 noindex(防止搜索引擎收录短链稀释目标页权重),确认要收录才打开;ROBOTS_USER_AGENTS:自定义 robots 规则命中的 UA 列表;MATOMO_*四件套:把每次访问同步推给 Matomo 分析平台(MATOMO_ENABLED=true+MATOMO_BASE_URL+MATOMO_SITE_ID+MATOMO_API_TOKEN),适合「短链入口 + Matomo 深度分析」的组合,选型参照 Matomo 官方部署文档。
十二、生产配置模板
PostgreSQL + Redis 生产形态的完整环境变量组(内存与磁盘标注:Shlink 容器内存上限 512M 起步即可,PostgreSQL 单独 512M1G,磁盘按访问量预留 visit 表空间——每 10 万次访问约占 5080MB):
name: shlink-5.1.8-stack
services:
shlink-app:
image: shlinkio/shlink:5.1.8
ports:
- "8132:8080"
environment:
# 域名与访问
DEFAULT_DOMAIN: "s.example.com"
IS_HTTPS_ENABLED: "true"
TIMEZONE: "Asia/Shanghai"
SHORT_URL_TRAILING_SLASH: "true"
# 数据库(密码走 secret 文件)
DB_DRIVER: "postgres"
DB_HOST: "shlink-db"
DB_NAME: "shlink"
DB_USER: "shlink"
DB_PASSWORD_FILE: "/run/secrets/shlink_db_pass"
# 跳转行为
REDIRECT_STATUS_CODE: "302"
DEFAULT_INVALID_SHORT_URL_REDIRECT: "https://www.example.com/"
DEFAULT_BASE_URL_REDIRECT: "https://www.example.com/"
# 统计与隐私
DISABLE_TRACKING_FROM: "192.168.1.0/24"
DISABLE_TRACK_PARAM: "nohit"
# 缓存
REDIS_SERVERS: "tcp://shlink-redis:6379"
REDIS_PUB_SUB_ENABLED: "false"
# 运维
TRUSTED_PROXIES: "10.89.0.0/16"
MEMORY_LIMIT: "512M"
GEOLITE_LICENSE_KEY: "${MAXMIND_KEY}" # 第三方 Key 不落盘:写进 compose 同目录 .env 文件(chmod 600),变量替换注入
secrets:
- shlink_db_pass
depends_on:
shlink-db:
condition: service_healthy
networks: [shlink-net]
shlink-db:
image: postgres:16-alpine
environment:
POSTGRES_DB: "shlink"
POSTGRES_USER: "shlink"
POSTGRES_PASSWORD: "q1w2E3r4"
volumes:
- shlink-db-data:/var/lib/postgresql/data
networks: [shlink-net]
shlink-redis:
image: redis:7
networks: [shlink-net]
volumes:
shlink-db-data:
networks:
shlink-net:
name: shlink-5.1.8-net
driver: bridge
secrets:
shlink_db_pass:
file: ./shlink_db_pass.txt
编排结构与 healthcheck 的完整说明(本模板的删减版)见 《Shlink 5.1.8 Docker Compose 部署指南》。反代 TLS 接入与 TRUSTED_PROXIES 的配合参照 《Nginx HTTPS 与证书配置方案(certbot/自签名)》。
十三、常见配置问题(实测沉淀)
13.1 设置了 SHORT_URL_TRAILING_SLASH=true,生成的短链怎么没有尾斜杠
生成 URL 固定无尾斜杠(5.x 生成侧源码无此分支)。该项的实测语义是访问侧容错:带尾斜杠的访问从 404(默认)变为正常跳转。想改生成结果是没有开关的——若下游系统强依赖尾斜杠形态,只能自定义 slug 以 / 结尾并开启多段 slug。
13.2 DEFAULT_INVALID_SHORT_URL_REDIRECT 设了但跳转状态码不是预期的 302
兜底跳转沿用全局 REDIRECT_STATUS_CODE(实测设 301 后无效短码访问返回 HTTP 301)。两者是乘法关系,规划兜底导流时要连状态码一起核对。
13.3 DISABLE_TRACK_PARAM 配了却还在统计
实测确认参数是精确匹配:访问 ?myp=1 不计数,但其他参数组合(如 ?myp=1&x=2)同样生效(键存在即命中);真正常见的失效原因是参数名大小写不一致,或该参数被写进了短链目标长 URL 而非短链访问 URL——拦截发生在跳转请求上,跳转之后的后续动作不再受控。
13.4 Redis 配了但短链查询还是慢 / 键里没有短码
用 redis-cli --scan --pattern 'Shlink*' 实测核对:只有 13 个左右键(元数据 + 少量哈希)是正常的——跳转缓存按短码粒度懒加载,没人点过的短链不在缓存里。若连元数据键都没有,先查 REDIS_SERVERS 格式(必须带 tcp:// 前缀)与网络连通性。缓存调优进阶见 《Shlink 5.1.8 常见问题与进阶实战》。
13.5 删短链报 "Impossible to delete ... since it has more than N visits"
这是 DELETE_SHORT_URL_THRESHOLD 保护在生效(实测默认 15),不是故障。脚本场景无交互输入会以退出码 2 终止且不删除;确认要删用 short-url:delete -i(ignore-threshold)。
十四、配置速查与系列导航
按场景速查:换域名 → 4.1;短链带斜杠 404 → 4.2;短码长度/大小写 → 第五章;连不上数据库 → 第六章;跳转 301/404 兜底 → 第七章;统计数据不要记 → 第八章;多实例部署 → 9.1/9.2;地理 Unknown → 10.1;删不掉短链 → 10.2/13.5;反代后 IP 不对 → 11.1。
系列文章:
- 《Shlink 5.1.8 介绍与选型指南》 — 特性全景、版本演进与选型对比
- 《Shlink 5.1.8 Docker Compose 部署指南》 — PostgreSQL/SQLite 双形态编排实测
- 本文 — 67 项配置参数全量详解与逐项实测
- 《Shlink 5.1.8 REST API 与 CLI 命令详解》 — API 全流程与 30+ CLI 命令清单
- 《Shlink 5.1.8 常见问题与进阶实战》 — 部署/统计类 FAQ 与进阶场景