docker 搭建 Shlink (self-hosted URL shortener)

Shlink适合单用户非公开用例。更轻量级/多用户/公开项目参考 4. 其他短链接项目

1. 注册MaxMind获取GeoLite2 key (可选)

用于显示访客地区。

注册一个MaxMind账号 https://www.maxmind.com/en/geolite2/signup

生成许可证密钥并自行保存,之后无法恢复 https://www.maxmind.com/en/accounts/current/license-key

2. 配置文件

docker-compose.yml

services:
  # 1. PostgreSQL 数据库
  db:
    image: postgres:18-alpine
    container_name: shlink_db
    environment:
      POSTGRES_USER: shlink
      POSTGRES_PASSWORD: use_openssl_to_radom
      POSTGRES_DB: shlink
    volumes:
      - ./shlink_db_data:/var/lib/postgresql/data
    restart: unless-stopped
    networks:
      - default
    logging:
      driver: "json-file"
      options:
        max-size: "10m"
        max-file: "3"

  # 2. Shlink 核心后端服务
  shlink:
    image: shlinkio/shlink:stable
    container_name: shlink_backend
    depends_on:
      - db
    environment:
      - DB_DRIVER=postgres
      - DB_USER=shlink
      - DB_PASSWORD=use_openssl_to_radom
      - DB_NAME=shlink
      - DB_HOST=db
      # 注意:配合反代使用时,这里应该改成你未来的实际域名,如 shlink.example.com
      - DEFAULT_DOMAIN=shlink-backend.example.com
      - IS_HTTPS_ENABLED=true
      - GEOLITE_LICENSE_KEY=  # 免费注册MaxMind获取GeoLite2 许可证密钥
    expose:
      - "8080"
    networks:
      - default
      - dockernetwork
    restart: unless-stopped
    logging:
      driver: "json-file"
      options:
        max-size: "10m"
        max-file: "3"

  # 3. Shlink 前端 Web 管理界面
  shlink-web-client:
    image: shlinkio/shlink-web-client:latest
    container_name: shlink_web
    expose:
      - "8080"
    depends_on:
      - shlink
    networks:
      - dockernetwork
    restart: unless-stopped
    logging:
      driver: "json-file"
      options:
        max-size: "10m"
        max-file: "3"

networks:
  dockernetwork:
    external: true

配置中的default用于后端和db连通,dockernetwork用于使用npm反代。

注意生成替换DB_PASSWORD

3. 启动和测试

启动容器

docker compose up -d

生成 API Key (用于在前端和后端通信),自行保存生成的key

docker compose exec shlink shlink api-key:generate

在npm反代 shlink_backendshlink_web ,这两个域名可以随便使用后端域名,并在waf设置IP白名单。此外,可以解析实际使用的一个或多个短域名到shlink_backend

在前端连接后端后,可以在 /manage-servers 导出服务器配置csv文件

创建短链接时,在Create a short URL点击Advanced options » 展开,输入一个new domain(实际使用的短域名),此短域名就会显示在manage-domains页面,可以编辑其根路径、404、无效路径的跳转。

在设置的Real-time updates中,可以设置更新频率,比如设置20 (分钟)

此外,测试正常后,可以考虑将shlink_backend固定为具体的版本如 image: shlinkio/shlink:5.0.0 。注意备份数据库。

4. 其他短链接项目

yourls,元老项目,更适合部署在传统php环境。我三年前用过这个项目,借助插件也能实现不少细分功能。

kutt,配置比较方便,支持多用户注册,多域名/根域名跳转/限时限次/设置访问密码等功能也有,还支持细分的删除和封禁范围,比较实用。

使用sqlite,轻量使用或测试使用。

services:
  kutt:
    image: kutt/kutt:latest
    container_name: kutt_app
    restart: unless-stopped
    expose:
      - "3000"
    volumes:
      - ./kutt_data:/var/lib/kutt
    environment:
      # 基础设置
      - PORT=3000
      - DEFAULT_DOMAIN= # 如果有公网 IP 或域名,请替换为你的域名
      - SITE_NAME=Kutt Test
      
      # 数据库设置 (使用内置 SQLite)
      - DB_FILENAME=/var/lib/kutt/data.sqlite
      
      # 安全设置 (生产环境必须修改为长随机字符串)
      - JWT_SECRET=
      
      # 管理员邮箱 (在网页端注册此邮箱,会自动获得管理员权限)
      - ADMIN_EMAILS=
      
      # 权限设置
      - DISALLOW_REGISTRATION=true     # 允许用户注册
      - DISALLOW_ANONYMOUS_LINKS=true    # 允许未登录用户生成短链
    networks:
      - dockernetwork

networks:
  dockernetwork:
    external: true

完整部署(PostgreSQL + Redis)参考,此配置我未进行完整测试

services:
  kutt:
    image: kutt/kutt:latest
    container_name: kutt_app
    restart: unless-stopped
    ports:
      - "3000:3000"
    environment:
      - PORT=3000
      - DEFAULT_DOMAIN=localhost:3000
      - SITE_NAME=Kutt Pro
      # 数据库配置
      - DB_HOST=postgres
      - DB_PORT=5432
      - DB_NAME=kutt
      - DB_USER=kutt_user
      - DB_PASSWORD=kutt_password
      # 缓存配置
      - REDIS_ENABLED=true
      - REDIS_HOST=redis
      - REDIS_PORT=6379
      - REDIS_PASSWORD=
      # 其他配置
      - JWT_SECRET=super_secret_jwt_key_change_me
      - ADMIN_EMAILS=admin@example.com
      - DISALLOW_REGISTRATION=false
      - DISALLOW_ANONYMOUS_LINKS=true
    depends_on:
      - postgres
      - redis

  postgres:
    image: postgres:15-alpine
    container_name: kutt_postgres
    restart: unless-stopped
    environment:
      - POSTGRES_DB=kutt
      - POSTGRES_USER=kutt_user
      - POSTGRES_PASSWORD=kutt_password
    volumes:
      - kutt_db:/var/lib/postgresql/data

  redis:
    image: redis:7-alpine
    container_name: kutt_redis
    restart: unless-stopped
    volumes:
      - kutt_redis_data:/data

volumes:
  kutt_db:
  kutt_redis_data:

Slash,更像是个人书签,附带实现了短链接功能。限制100个链接数。docker-compose.yml

Sink,完全运行在cloudflare workers/KV。挺多使用cloudflare部署的项目都设计的挺不错,但我还是觉得部署在vps更能给我安全感(主要是没有请求次数焦虑)。

此外还有Chhoto URL、shrtn.io 等项目,功能精简,stars数较少,我没有实际部署测试,感兴趣可以看一下。

参考

https://shlink.io/documentation/install-docker-image/

https://shlink.io/documentation/geolite-license-key/

© 版权声明
THE END
喜欢就支持一下吧
点赞0 分享
评论 抢沙发
头像
欢迎您留下宝贵的见解!无需注册,过短或乱码评论会被屏蔽。
提交
头像

昵称

取消
昵称表情代码图片快捷回复

    暂无评论内容