惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

AI
AI
TaoSecurity Blog
TaoSecurity Blog
H
Heimdal Security Blog
Help Net Security
Help Net Security
cs.CV updates on arXiv.org
cs.CV updates on arXiv.org
Microsoft Azure Blog
Microsoft Azure Blog
www.infosecurity-magazine.com
www.infosecurity-magazine.com
Google DeepMind News
Google DeepMind News
爱范儿
爱范儿
The Cloudflare Blog
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
人人都是产品经理
人人都是产品经理
大猫的无限游戏
大猫的无限游戏
N
News | PayPal Newsroom
V2EX - 技术
V2EX - 技术
博客园 - 【当耐特】
D
Darknet – Hacking Tools, Hacker News & Cyber Security
S
Secure Thoughts
C
CERT Recently Published Vulnerability Notes
罗磊的独立博客
Exploit-DB.com RSS Feed
Exploit-DB.com RSS Feed
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
P
Privacy & Cybersecurity Law Blog
有赞技术团队
有赞技术团队
S
Schneier on Security
S
SegmentFault 最新的问题
Google Online Security Blog
Google Online Security Blog
H
Hacker News: Front Page
The Last Watchdog
The Last Watchdog
Schneier on Security
Schneier on Security
PCI Perspectives
PCI Perspectives
IT之家
IT之家
Project Zero
Project Zero
博客园 - 司徒正美
P
Privacy International News Feed
Recent Commits to openclaw:main
Recent Commits to openclaw:main
Jina AI
Jina AI
Security Latest
Security Latest
Hacker News - Newest:
Hacker News - Newest: "LLM"
腾讯CDC
C
CXSECURITY Database RSS Feed - CXSecurity.com
阮一峰的网络日志
阮一峰的网络日志
C
Check Point Blog
aimingoo的专栏
aimingoo的专栏
V
Vulnerabilities – Threatpost
W
WeLiveSecurity
NISL@THU
NISL@THU
Webroot Blog
Webroot Blog
N
Netflix TechBlog - Medium
L
Lohrmann on Cybersecurity

烧饼博客

Ubuntu 24.04 Noble 升级 Ubuntu 26.04 Resolute WSL 2 使用 Docker 桥接模式网络访问 HTTPS 超时的解决方法 Debian / Ubuntu 下使用 nginx-acme 自动签发并配置 SSL 证书 使用 acme.sh 配置 Let's Encrypt 签发的 IP 地址 SSL 证书 RDAP.SS - 基于 RDAP 协议的 Whois 查询网站 Debian 使用 extrepo 配置第三方软件源 升级 Debian 后 GitLab PostgreSQL 无法启动的解决方法 Debian 12 Bookworm 升级 Debian 13 Trixie Ubuntu 22.04 Jammy 升级 Ubuntu 24.04 Noble Docker 安装 FreshRSS 教程 Debian 安装 Nextcloud 服务端 Debian 双栈网络时开启 IPv4 优先 Debian / Ubuntu 使用源安装 LAMP 教程 Debian / Ubuntu 使用源安装 LEMP 教程
Docker 安装 Shlink 自建短网址
Showfom · 2022-04-27 · via 烧饼博客

本文将指导使用 Docker 安装 Shlink 搭建自建短网址服务。

PS:本文同时适用于任何可安装 Docker 的 Linux 发行版。

#什么是短网址?

短网址,即 URL Shortener (缩略网址服务),一般我们使用 HTTP 协议301302 响应码,现在也有使用 307308 来跳转一个长网址,简单的区别:

状态码名称是否永久是否保留请求方法浏览器缓存
301Moved Permanently✅ 永久❌ 可能改为 GET会缓存
302Found❌ 临时❌ 可能改为 GET不缓存
307Temporary Redirect❌ 临时✅ 保留不缓存
308Permanent Redirect✅ 永久✅ 保留会缓存

MDN 上有对这几个状态码的详细介绍:

301302 有一个最重要的区别,前者会在浏览器留下缓存,后者不会,导致如果你需要精确的统计访客,尤其是有一些使用一个浏览器的重复访客会不准确,但是影响不大,而使用 302 每次都会请求服务器造成服务器资源紧张,所以一般没有特殊需求的话,使用 301 就行。

举一个典型的 301 跳转的例子:

root@debian ~ # curl -I http://u.sb/ -A Mozilla
HTTP/1.1 301 Moved Permanently
Date: Tue, 26 Apr 2022 18:28:14 GMT
Content-Type: text/html
Content-Length: 162
Location: https://u.sb/

我们可以看到,使用浏览器访问 http://u.sb/ 的时候,会返回 HTTP/1.1 301 Moved Permanently 状态,对应跳转到 Location https://u.sb/

#市面上开源和收费的短网址源码

众所周知,本人的短域名贼多,对各种短网址程序都有所研究,市面上主要有这几款免费的短网址程序:

  • Blink - Easy-to-host,SSO-integrated,CDN-powered link shortener (+decoupled analytics) for teams。(Source Code) AGPL-3.0 Nodejs
  • Kutt - A modern URL shortener with support for custom domains。(Source Code) MIT Nodejs
  • Polr - Modern,minimalist,modular,and lightweight URL shortener。(Source Code) GPL-2.0 PHP
  • Shlink - URL shortener with REST API and command line interface。Includes official progressive web application and docker images。(Source CodeClients) MIT PHP
  • YOURLS - YOURLS is a set of PHP scripts that will allow you to run Your Own URL Shortener。Features include password protection,URL customization,bookmarklets,statistics,API,plugins,jsonp。(Source Code) MIT PHP

我基本上都安装使用过,数据量大了以后性能基本惨不忍睹,对比以后还是使用 PHP Swoole 写的 Shlink 稍微占优,所以本文推荐安装 Shlink。

至于收费的?呵呵,没一个好用的,建议别去踩坑,我都帮你们踩过了。。。

广告:因为市面上没有好用的收费短网址,所以我们做了一个 S.EE 欢迎购买使用~

#安装 Docker 和 Docker Compose

Debian 和 Ubuntu 系统请参考本站教程

其他 Linux 系统可以使用 Docker 官方的脚本安装 Docker 和 Docker Compose:

curl -fsSL https://get.docker.com -o get-docker.sh
sh get-docker.sh

参考官网的安装教程,我们可以把 Server 和 Web Client 装在一个地方方便管理。

首先我们新建 /opt/shlink/opt/shlink/data 目录:

mkdir -p /opt/shlink
mkdir -p /opt/shlink/data

然后我们新建一个 compose.yaml 文件,假设你的域名是 example.com,放在 /opt/shlink/compose.yaml

cat > /opt/shlink/compose.yaml << EOF
services:
    shlink:
      image: shlinkio/shlink:stable
      container_name: shlink
      ports:
        - 127.0.0.1:8080:8080
      environment:
        - DEFAULT_DOMAIN=example.com
        - IS_HTTPS_ENABLED=true
        - GEOLITE_LICENSE_KEY=
        - DB_DRIVER=maria
        - DB_NAME=shlink
        - DB_USER=shlink
        - DB_PASSWORD=随机密码1
        - DB_HOST=db
        - DB_PORT=3306
        - TIMEZONE=UTC
        - REDIRECT_STATUS_CODE=301
      depends_on:
        db:
          condition: service_healthy
      restart: always

    db:
      image: mariadb:lts
      container_name: db
      ports:
        - 127.0.0.1:3306:3306
      environment:
        - MYSQL_ROOT_PASSWORD=随机密码2
        - MYSQL_DATABASE=shlink
        - MYSQL_USER=shlink
        - MYSQL_PASSWORD=随机密码1
      volumes:
        - /opt/shlink/data:/var/lib/mysql
      healthcheck:
        test: ["CMD", "healthcheck.sh", "--connect", "--innodb_initialized"]
        interval: 10s
        timeout: 5s
        retries: 3
        start_period: 30s
      restart: always

    shlink-web-client:
        image: shlinkio/shlink-web-client:stable
        container_name: shlink-web-client
        ports:
          - 127.0.0.1:8081:8080
        restart: always
EOF

如果希望有用户登录等功能,则可以用官方的下一代面板 shlink-dashboard,这里我们可以让 shlink-dashboard 容器和 shlink 容器共用一个 MariaDB 容器和用户,首先还是一样建立 docker compose 文件:

cat > /opt/shlink/compose.yaml << EOF
services:
    shlink:
      image: shlinkio/shlink:stable
      container_name: shlink
      ports:
        - 127.0.0.1:8080:8080
      environment:
        - DEFAULT_DOMAIN=example.com
        - IS_HTTPS_ENABLED=true
        - GEOLITE_LICENSE_KEY=
        - DB_DRIVER=maria
        - DB_NAME=shlink
        - DB_USER=shlink
        - DB_PASSWORD=随机密码1
        - DB_HOST=db
        - DB_PORT=3306
        - TIMEZONE=UTC
        - REDIRECT_STATUS_CODE=301
      depends_on:
        db:
          condition: service_healthy
      restart: always

    db:
      image: mariadb:lts
      container_name: db
      ports:
        - 127.0.0.1:3306:3306
      environment:
        - MYSQL_ROOT_PASSWORD=随机密码2
        - MYSQL_DATABASE=shlink
        - MYSQL_USER=shlink
        - MYSQL_PASSWORD=随机密码1
      volumes:
        - /opt/shlink/data:/var/lib/mysql
        - /opt/shlink/mariadb-init:/docker-entrypoint-initdb.d
      healthcheck:
        test: ["CMD", "healthcheck.sh", "--connect", "--innodb_initialized"]
        interval: 10s
        timeout: 5s
        retries: 3
        start_period: 30s
      restart: always

    shlink-dashboard:
      image: shlinkio/shlink-dashboard:stable
      container_name: shlink-dashboard
      ports:
        - '127.0.0.1:8081:8080'
      environment:
        - SHLINK_DASHBOARD_DB_DRIVER=mariadb
        - SHLINK_DASHBOARD_DB_HOST=db
        - SHLINK_DASHBOARD_DB_PORT=3306
        - SHLINK_DASHBOARD_DB_USER=shlink
        - SHLINK_DASHBOARD_DB_PASSWORD=随机密码1
        - SHLINK_DASHBOARD_DB_NAME=shlink-dashboard
        - SHLINK_DASHBOARD_SESSION_SECRETS=secret1,secret2  # 设置会话加密,需要设置多个高强度随机值,用半角逗号隔开
      depends_on:
        db:
          condition: service_healthy
      restart: always
EOF

然后创建一个 /opt/shlink/mariadb-init/01-create-databases.sql 文件

mkdir -p /opt/shlink/mariadb-init

cat > /opt/shlink/mariadb-init/01-create-databases.sql << 'EOF'
CREATE DATABASE IF NOT EXISTS `shlink-dashboard`;
GRANT ALL PRIVILEGES ON `shlink-dashboard`.* TO 'shlink'@'%';
FLUSH PRIVILEGES;
EOF

然后我们可以先启动 MariaDB 容器创建用户和数据库:

cd /opt/shlink
docker compose up db -d

验证下是否成功:

docker exec -it db mariadb -u root -p'随机密码2' -e "SHOW DATABASES;"

看到有 shlinkshlink-dashboard 两个数据库就成功了:

# docker exec -it db mariadb -u root -p'随机密码2' -e "SHOW DATABASES;"
+--------------------+
| Database           |
+--------------------+
| information_schema |
| mysql              |
| performance_schema |
| shlink             |
| shlink-dashboard   |
| sys                |
+--------------------+

注意:

GEOLITE_LICENSE_KEY 需要在 Maxmind 注册帐号获取,可以参考《使用 Docker 安装 Plausible Analytics 自建网站统计

MYSQL_ROOT_PASSWORDMYSQL_PASSWORD 记得设置两个随机的密码,同时 MYSQL_PASSWORD 需要和 DB_PASSWORD 一致。

更多的环境变量参数可以参考这里

然后拉取所有的 Docker 镜像并运行:

docker compose pull
docker compose up -d

然后获取一个 API Key:

docker exec -it shlink shlink api-key:generate

image.png

注意第一个 shlink 是 Docker 容器名字,第二个 shlink 是命令名称。

所有 API 命令如下:

docker exec -it shlink shlink

记得保存你的 API Key,下面会要用到。

#安装配置 Nginx 反代

我们的 Docker Compose 配置文件中,Shlink Server 服务监听在 127.0.0.1:8080 端口,Shlink Web Client 监听在 127.0.0.1:8081 端口,所以我们需要配置 Nginx 反代来访问,假设你短网址是 https://example.com/ Web 客户端是 https://app.example.com/

example.com 段配置:

	location / {
		proxy_set_header X-Real-IP $remote_addr;
		proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
		proxy_set_header Host $http_host;
		proxy_http_version 1.1;
		proxy_set_header Upgrade $http_upgrade;
		proxy_redirect off;
		proxy_set_header        X-Forwarded-Proto $scheme;
		proxy_connect_timeout       300;
		proxy_send_timeout          300;
		proxy_read_timeout          300;
		send_timeout                300;
		proxy_pass http://127.0.0.1:8080;
	}

app.example.com 段配置:

	location / {
		proxy_set_header X-Real-IP $remote_addr;
		proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
		proxy_set_header Host $http_host;
		proxy_http_version 1.1;
		proxy_set_header Upgrade $http_upgrade;
		proxy_redirect off;
		proxy_set_header        X-Forwarded-Proto $scheme;
		proxy_connect_timeout       300;
		proxy_send_timeout          300;
		proxy_read_timeout          300;
		send_timeout                300;
		proxy_pass http://127.0.0.1:8081;
	}

最后记得参考本站 Nginx SSL 配置教程加上 SSL 证书后,即可访问 https://app.example.com/

点击 + Add a server 添加你的 Shlink 服务:

image.png

输入名称,URL 和 API Key 以后点击 Create server 即可使用:

image.png

如果你懒得搭建 Web Client,也可以使用官方现成的服务:

Shlink Web Client

数据都是储存在浏览器本地的,可放心使用。

如果搭建的 Shlink Dashboard,则默认账号密码都是 admin, 登录以后记得修改哦!

直接使用 Docker Compose 升级并删除旧的镜像文件:

cd /opt/shlink
docker compose pull
docker compose up -d
docker system prune -f

切记不要跨多个版本升级,最好按照每个小版本的最新补丁顺序更新 Shlink。

比如,要从 3.2.1 版本升级到 3.4.0,先更新到 3.3.2,然后再升级到 3.4.0,可以自行替换 Docker 镜像里的 stable 标签为具体版本号来更新升级。

可以参考《使用 Docker 安装 Mailcow 自建域名邮箱》。

我们可以定期备份数据库,导出命令如下:

docker exec db mariadb-dump -u root --password='随机密码2' --databases shlink > shlink-all-$(date +"%Y_%m_%d_%I_%M_%p").sql

如果装了 shlink-dashboard

docker exec db mariadb-dump -u root --password='随机密码2' --databases shlink shlink-dashboard > shlink-all-$(date +"%Y_%m_%d_%I_%M_%p").sql

请替换 随机密码2 为你的数据库 root 密码。