Skip to content

短链接工具 Shlink 部署简单而又功能强大 支持多种数据库

前言

在上一篇介绍 Lynx 的文章有提到,我目前使用的短链接工具已经从 Lynx 换到了 Shlink,主要有以下几个原因:

  • Shlink 自带更为完善的统计功能,不需要像 Lynx 一样开启前端跳转对接 Umami,跳转速度更快
  • 功能更加丰富,支持设置访问次数、到期时间等等
  • 支持将 404 页面、不存在的短链接重定向到其他页面
  • 支持包括 SQLite、MySQL、PostgreSQL 在内的多种数据库,数据存储更加的灵活
  • 导入、导出功能比较完善,无论是迁移到 Shlink 还是迁移到其他短链接工具都很方便

在对比了同样流行的 YOURLS 和 Kutt 之后,目前感觉 Shlink 更加符合我的需求

  • YOURLS 目前好像还是只支持 MySQL 数据库并且面板风格“复古”
  • Kutt 注重商业化,开源版的部署文档过于简陋

部署

Shlink 的部署可以直接使用 Docker Compose,下面这个示例是 SQLite 作为数据库运行的 Shlink。

只推荐数据量与访问量极少的情况下使用 SQLite 或者作为测试环境体验一下 Shlink 的各项功能是否满足需求,如果是正式环境建议配置其他数据库。

环境变量中的 INITIAL_API_KEY 为面板的登录凭证,可以在环境变量中提前配置,免去后期进入容器生成

yaml
services:
  shlink:
    image: shlinkio/shlink:stable
    container_name: shlink
    restart: always
    network_mode: host
    environment:
      PORT: 8080
      DEFAULT_DOMAIN: 'go.exmaple.com'
      IS_HTTPS_ENABLED: 'true'
      INITIAL_API_KEY: '<API_KEY>'

配置

面板

当你的域名配置好反向代理后,直接访问域名时,你会惊奇的发现怎么没有进入面板,而是直接返回了 404 页面。

404 页面
404 页面

实际上是因为 shlinkio/shlink 这个镜像中并没有包含面板,Web 面板需要单独部署 shlinkio/shlink-web-client 这个镜像。

不过我们可以直接用官方提供的 https://app.shlink.io,既省去了部署面板的麻烦,又能一直让面板保持最新版本。

同时,这个 Web 面板完全运行在浏览器中,所有的数据仍然存储在我们自己的服务器上,不会上传到官方服务器,也不用担心隐私问题。

添加服务器
添加服务器

接着只需要填写上你的 URL 与环境变量中设置的 INITIAL_API_KEY 就能进入面板了。

服务器信息
服务器信息

短链接

对于简单的需求,在首页就可以添加短链接,但你会发现两个问题:

  • blog/zc 添加之后就变成了 blog-zc
  • 长域名被解析成了对应页面的 title,如果页面过多就不太好区分了
添加短链接
添加短链接

为了解决这两个问题,我们可以在环境变量中添加以下两项

yaml
MULTI_SEGMENT_SLUGS_ENABLED: true # 支持多 / 的短链接
AUTO_RESOLVE_TITLES: false # 关闭自动解析标题

如果你想要创建限制到期时间与访问次数的短链接,则可以在 “Create short URL” 页面中创建

到期时间与访问次数
到期时间与访问次数

此外,你还可以使用下面这个环境变量设置自动生成的 slug 长度

yaml
DEFAULT_SHORT_CODES_LENGTH: 6 # 默认值为 5,最小值为 4

重定向

对于根路径、404 页面以及不存在短链接,在 “Manage domains” 中设置后可以直接将其重定向到你的网站首页。

重定向
重定向

地理位置

你可能会发现,查看访问记录时的城市都显示的 Unknown

地理位置
地理位置

这是因为 Shlink 识别 IP 位置默认使用的是 GeoLite2,正常情况下,我们需要在环境变量中加上 GEOLITE_LICENSE_KEY

yaml
GEOLITE_LICENSE_KEY: kjh23ljkbndskj345

但是注册 MaxMind 比较麻烦,其实我们还可以直接下载 GeoLite2-City.mmdb 把它映射到容器内

GeoLite2-City.mmdb夸克网盘 / UC 网盘

唯一的缺点就是 IP 对应的城市不会实时更新,后续想要更新的话要替换新的 GeoLite2-City.mmdb

yaml
volumes:
  - /opt/shlink/GeoLite2-City.mmdb:/etc/shlink/data/GeoLite2-City.mmdb

数据库

在测试完成后,强烈建议将 Shlink 从 SQLite 切换到其他数据库,直接在环境变量中配置即可

yaml
DB_DRIVER: 'postgres' # mysql, maria, postgres, mssql
DB_USER: 'shlink'
DB_PASSWORD: '<password>'
DB_HOST: '127.0.0.1'
DB_NAME: 'shlink' # 可选,默认为 shlink
DB_PORT: 5432 # 可选,默认为数据库默认端口,如 MySQL 为 3306,PostgreSQL 为 5432

导入

Shlink 支持从 bitly、yourls、csv、shlink、kutt 中导入短链接,但可惜我之前使用的 Lynx 并不支持直接导入 Shlink。

不过可以将 Lynx 的短链接导出 CSV,再将它整理成以下格式

txt
Long URL,Tags,Domain,Short code,Title
https://shlink.io,foo|bar|baz,,123,
https://example.com,,example.com,456,my title

接着将 CSV 文件映射到容器内,在容器内执行 bin/cli short-url:import csv,就可以将所有短链接导入了

sh
$ bin/cli short-url:import csv

 What's the path for the CSV file you want to import:
 > ./my_links.csv

 What's the delimiter used to separate values? [Comma]:
  [,] Comma
  [;] Semicolon
> ,

https://shlink.io: Imported
https://example.com: Imported

不过还是有两个小问题:

  1. 导入后的短链接中的 / 又变成了 -
  2. 不支持短链接的创建时间一起导入,

目前没有找到优雅的解决方法,只能直接通过 SQL 语句批量修改数据库。