Kutt 3.2.6 介绍与选型指南

Kutt 3.2.6 自托管 URL 短链服务全景介绍与同类选型:Svelte+Node.js 技术栈、SQLite/Postgres/MySQL+可选 Redis 存储架构、双认证 API、实测功能特性与快速上手,并与 Shlink、YOURLS、Chhoto URL 量化对比。

KuttKutt自托管DockerNode.jsPostgreSQL2026/11/02

Kutt 3.2.6 介绍与选型指南

目标:全面介绍 Kutt 的定位、架构、功能与限制,给出自托管短链服务的选型依据;全部结论基于 Ubuntu 24.04 宿主机上 kutt/kutt:v3.2.6 官方镜像 + Postgres 16 + Redis 7 实测栈(2026-11-01 验证),命令与回显均为真实运行结果。

一、环境信息

本文实测环境:

  • 操作系统:Ubuntu 24.04.5 LTS(x86_64)
  • Docker 版本:29.9.2(Docker Compose v5.6.1 插件)
  • Kutt 版本:v3.2.6(官方镜像 kutt/kutt:v3.2.6,镜像 ID fa3d24a89b04,发布于 2026-07-05)
  • 应用运行时:Node.js 22.23.1(镜像基座 node:22-alpine)
  • 数据库:PostgreSQL 16(postgres:16-alpine);同版本亦实测 SQLite 最小形态
  • 缓存/队列:Redis 7(redis:7-alpine)
  • 服务端口:应用内 3000;宿主机映射 8153
  • 管理员账号:admin@kutt.local / q1w2e3r4(首启向导创建)

⚠️ 版本重要提示:Kutt 自 3.x 起已彻底移除 MongoDB,改用 knex 统一访问 SQLite / PostgreSQL / MySQL(MariaDB) 三类关系库,Redis 降级为"可选"组件(REDIS_ENABLED 开关)。网上大量旧教程仍写"Kutt = MongoDB + Redis",那是 2.x 时代的形态,选型与部署时务必以官方仓库 thedevs-network/kutt(注意:旧组织名 thedevs-kutt/kutt 已 404)当前 README 为准。

二、软件概述

Kutt 是一个开源的自托管 URL 短链服务,主打"零配置即可跑起来":单容器 + SQLite 文件即可提供完整的短链生成、跳转、统计与管理功能,同时支持自定义域名、密码保护、有效期、访问统计等运营特性。

  • 项目定位:个人与小团队的"自建 bit.ly",对标 SaaS 短链服务的自托管替代;
  • 开源协议:MIT(GitHub API 实测返回 license.spdx_id = MIT);
  • 维护方:The Devs Network(GitHub 组织 thedevs-network);
  • 技术栈:前端 Svelte(SPA 静态资源内置于镜像),后端 Express + knex + Passport,任务队列 Bull;
  • 社区数据(2026-11-02 经 GitHub API 实测):
curl -s https://api.github.com/repos/thedevs-network/kutt | \
  python3 -c "import json,sys; d=json.load(sys.stdin); print('stars:', d['stargazers_count'], '| forks:', d['forks_count'], '| open_issues:', d['open_issues_count'], '| license:', d['license']['spdx_id'], '| pushed_at:', d['pushed_at'])"
stars: 11188 | forks: 1519 | open_issues: 93 | license: MIT | pushed_at: 2026-10-19T07:55:33Z
  • 发布节奏(GitHub Releases 实测近 5 版):
v3.2.6  2026-07-05
v3.2.5  2026-05-17
v3.2.4  2026-05-17
v3.2.3  2025-02-06
v3.2.2  2025-01-24

3.2.x 补丁迭代集中在 2025-01 至 2026-07,主干功能(knex 多库、角色体系、统计)在 3.2.0 一代已定型,当前处于稳定维护期。

💡 技术拓展:短链服务的存储选型不止本文所用的 Postgres。主流方案对比——

方案特点适用场景
SQLite零外部依赖,单文件即库个人/小规模、单机部署
PostgreSQL事务与并发强,jsonb 存统计维度团队生产环境(本文实测)
MySQL/MariaDB运维生态成熟已有 MySQL 基础设施的团队
MongoDB文档模型,Kutt 2.x 旧形态Kutt 3.x 已弃用,新项目不再考虑

本文实测采用 PostgreSQL 16(DB_CLIENT=pg),理由是并发写统计更稳、且与官方 docker-compose.postgres.yml 变体一致;SQLite 形态同样完成最小化实测(见第五章)。

三、核心架构

Kutt 是单体 Node.js 应用:同一进程同时提供 Web 页面(Svelte SPA + 服务端渲染局部模板)、REST API 与短链跳转端点,数据面由 knex 落到关系库,Redis(可选)承担缓存与异步队列。

3.1 请求链路

  • 短链跳转:GET /<address> → 查库/查 Redis 链接缓存(键 l:<address>:)→ 302 重定向到目标 URL → 访问事件入 Bull 队列(bull:visit:*)异步写入 visits 表;
  • 管理 API:/api/v2/*(同时挂载 /api/* 别名),经 Passport 双策略认证后走 knex;
  • 统计查询:GET /api/v2/links/:id/stats 从 visits 表按日聚合,结果在 Redis 缓存 60 秒(键 s:<link_id>)。

实测 Redis 开启后的键分布(redis-cli keys '*' 原样回显):

s:1
u:7sGm14IdbxoknkpnItuKQVRTMBaucEQscN7kAXsJ
l:kutt-proj:
bull:visit:id

四类键分别是:统计缓存(s:)、API key 用户缓存(u:)、短链跳转缓存(l:)、访问队列(bull:)。

3.2 数据模型

Postgres 库共 8 张表(\dt 实测回显):

 public | domains              | table
 public | hosts                | table
 public | ips                  | table
 public | knex_migrations      | table
 public | knex_migrations_lock | table
 public | links                | table
 public | users                | table
 public | visits               | table

links 存短链本体(address/target/password/expire_in/visit_count 等),visits 按"每链接每天一行"聚合统计(浏览器/操作系统/国家/referrer 分列计数),domains 与 hosts 支撑自定义域名,ips 记录访问来源。迁移共 10 个文件,容器启动时自动执行(CMD npm run migrate && npm start),实测首启日志:

> kutt@3.2.6 migrate
> knex migrate:latest

Batch 1 run: 10 migrations

> kutt@3.2.6 start
> node server/server.js --production

> Ready on http://localhost:3000

3.3 认证与角色体系

Kutt 3.x 的 API 认证有两条独立通道(源码 server/passport.js 实测核对):

  • JWT:登录后签发,只从 Cookie token 提取(jwtFromRequest: req => req.cookies?.token),Authorization: Bearer 头不生效——这是从旧版 API 迁移过来最常见的 401 原因;
  • API key:登录用户经 POST /api/v2/auth/apikey 生成,请求带 x-api-key: <key> 头即可,适合脚本与第三方集成。

角色分 ADMIN 与 USER:全新实例没有任何用户时,首页 302 到 /create-admin 首启向导,创建的账号直接为 ADMIN 且免邮箱验证;普通用户注册(/auth/signup)则要求 MAIL_ENABLED=true(需 SMTP 验证),实测未配邮件时返回:

{"error":"Unauthorized."}

四、功能特性

以下能力全部在实测栈(8153 端口)逐条验证:

  • 短链生成:随机 6 位地址(LINK_LENGTH=6,字符集默认剔除易混淆的 oO0iIl1j);实测 POST /api/v2/links 传 {"target":"https://www.quzuo.net","description":"quzuo 首页"} 返回:
{"id":"3a39e49f-d572-4250-98f2-f79f6f3619c8","address":"6ZErgk","description":"quzuo 首页","banned":false,"password":false,"expire_in":null,"target":"https://www.quzuo.net","visit_count":0,"link":"https://localhost:8153/6ZErgk"}
  • 自定义 slug / 密码保护 / 有效期:customurl、password、expire_in(ms 时长字符串)三字段实测均生效;expire_in:"30d" 存库为 2026-12-01T16:36:36.88+00;带密码短链访问时返回密码输入页,POST /api/v2/links/:id/protected 校验后返回目标地址;过期链接由内置 cron 每 30 秒自动清理;
  • 访问统计:浏览器/操作系统/国家/referrer 四维 + 按小时/日/周/月曲线。实测 3 次浏览器 UA 访问后:
lastDay total: 3
browser: [{'name': 'chrome', 'value': 3}]
os: [{'name': 'linux', 'value': 3}]
referrer: [{'name': 'google[dot]com', 'value': 3}]

注意两个实测行为:重定向为 302(非 301,跳转不缓存);统计走 isbot 过滤——curl 默认 UA 的 5 次访问全部不计入,浏览器 UA 访问才计数;

  • 管理面:ADMIN 可用 GET /api/v2/links/admin、/api/v2/users/admin 纵览全库链接与用户,POST /api/v2/links/admin/ban/:id 封禁(被封链接访问 302 到 /banned);
  • 其他:自定义域名(/add-domain 页面 + domains/hosts 表)、OIDC 单点登录、邮件(验证/找回/举报)、可选限流(ENABLE_RATE_LIMIT,依赖 Redis)、匿名短链开关(默认关闭)、健康检查 GET /api/v2/health 返回纯文本 OK。

五、快速开始(最小可用示例)

最小形态只需一个容器 + 一个 SQLite 文件,无需任何外部数据库。实测命令与回显:

docker run -d --name kutt-sqlite-test -p 127.0.0.1:8157:3000 \
  -e JWT_SECRET=$(openssl rand -hex 32) \
  -e DEFAULT_DOMAIN=localhost:8157 \
  kutt/kutt:v3.2.6
sleep 12 && curl -s http://localhost:8157/api/v2/health
Batch 1 run: 10 migrations
> Ready on http://localhost:3000
OK

健康检查通过后,浏览器打开 http://localhost:8157 会自动进入 /create-admin 首启向导,设置管理员邮箱与密码(≥8 位)即可开始使用。此时直接调 API 创建短链会返回:

{"error":"Unauthorized."}

这是预期行为:默认 DISALLOW_ANONYMOUS_LINKS=true 禁止匿名建链,需带 JWT(Cookie)或 x-api-key 认证,或显式关闭该开关。SQLite 数据文件实测落在容器内 /kutt/db/data(106 KB 起步),挂载持久化即可备份全部数据。

六、适用场景与限制

适合:

  1. 个人/小团队自建短链域名,追求"一个容器跑全部"(SQLite 形态零外部依赖);
  2. 需要 API 集成(浏览器扩展、脚本批量建链)——x-api-key 通道简单直接;
  3. 需要基础运营统计(来源/设备/趋势)与管理员治理(封禁、用户管理)的场景。

限制(实测确认):

  1. 普通用户注册强制依赖 SMTP:MAIL_ENABLED=false 时 /auth/signup 直接拒绝,只能靠首启向导建 ADMIN 账号——多用户开放注册场景必须先配邮件;
  2. 统计有 60 秒缓存 + bot 过滤:压测脚本/监控探针对短链的访问不计入统计,stats 接口结果最长滞后 60 秒;
  3. 跳转固定 302:对"短链永久迁移做 301 SEO 权重传递"的需求不适用;
  4. API 无批量端点:批量建链需逐条调用;删除/ban 均要求链接 UUID(传 6 位 address 报 ID is invalid.);
  5. 自定义域名的 HTTPS 证书需自备(CUSTOM_DOMAIN_USE_HTTPS 仅控制链接协议前缀,不签发证书)。

七、同类选型对比

与已在本平台完成实测部署的三个自托管短链组件横向对比(数据为 2026-11-02 GitHub API 实查;各组件详细评估见其选型篇):

维度Kutt 3.2.6Shlink 5.1.8YOURLS 1.10.6Chhoto URL 7.10.3
技术栈Node.js 22 + SveltePHP (Swoole/RoadRunner)PHPRust 单二进制
存储SQLite/PG/MySQL + 可选 RedisPostgreSQL/MySQL/SQLiteMySQL 必需SQLite
Stars / License11188 / MIT5398 / MIT12295 / MIT996 / MIT
最新版本v3.2.6 (2026-07-05)v5.1.8 (2026-10-21)1.10.6 (2026-08-30)v7.10.3
API 认证JWT(Cookie) + x-api-keyBearer Token RESTsignature APIBasic Token
管理界面Svelte SPA + ADMIN 治理视图独立 Web 客户端(shlink-web)内置后台内置极简后台
统计维度浏览器/OS/国家/referrer更细(含短链级实时)基础点击计数基础点击计数
部署复杂度低(单容器即可)中(需 DB+可选 Redis)中(PHP+MySQL 栈)最低(单二进制)
特色密码保护/有效期/封禁/OIDC域名池/重定向规则/CLI 生态插件生态最大资源占用最小

选型建议:

  • 要"功能全 + 界面现代 + 单容器起步" → Kutt(密码/有效期/封禁/OIDC 内置,SQLite 起步 PG 扩展);
  • 要"营销级统计 + 多域名池 + CLI 自动化" → Shlink;
  • 已有 PHP/MySQL 栈、要插件生态 → YOURLS;
  • 只要极简跳转、资源占用优先 → Chhoto URL。

八、参考链接

Kutt 3.2.6 介绍与选型指南 - Quzuo