自建 Iconfy API 服务:解决国内访问不稳定问题

Iconify 是一套面向开发人员和设计师的图标工具生态,它以统一的方式整合了200 多个开源图标集超过 27.5 万个图标,是前端开发中极为常用的开源图标库。

但 Iconify 官方 API 服务部署在国外,国内访问时经常出现网络波动、加载缓慢甚至失败的情况。为了保证项目中图标使用的稳定性,我选择自建 Iconify API 服务,以此获得更流畅的开发和使用体验。

先明确:你的项目是如何使用 Iconify 的?

自建 Iconify API 服务仅对「通过网络请求引入图标」的场景有效;如果你的项目是通过「npm 包方式引入 Iconify 图标」,本身就不需要额外部署服务,也无需自建 API。

npm 包方式引入(无需自建 API)

这种方式是将图标集以 npm 包的形式安装到项目中,比如我之前写的《iconfy 配置自动引入 Vue3+Vite3》一文,就是通过自动导入 @iconify-json/<图标集名称> 包来实现图标使用的。

优点: 实现了按需引入,即不是一次性引入所有的图标

缺点:

每次添加新的图标集项目的 package.json 文件中都会新增对应的 @iconify-json/* 依赖,但一个图标集可能只引入了一个图标。

且个人开发过程中,图标样式往往没法一步确定,经常需要反复替换、调整。这种情况下,先前安装的图标集 npm 包就会变成冗余依赖。诚然这其实不影响项目打包 ------Vite 或 Webpack 这类构建工具,本身会自动分析依赖树,只打包项目中实际用到的图标代码,不会因为安装了多余的图标集包就显著增加打包体积。

(不过本人有点 "代码洁癖",看着 package.json 里躺着一堆用不上的 @iconify-json/* 依赖就觉得不舒服,这纯属是无伤大雅的个人习惯~)

这种方式的特征也是缺点每次添加新的图标集,项目的 package.json 文件中都会新增对应的 @iconify-json/* 依赖。

网络请求方式引入(适合自建 API)

如果不想通过 npm 安装图标包,也可以使用 Iconify 官方提供的对应语言组件,通过网络请求动态加载图标。这里以 Vue 项目为例,基础使用代码如下:

vue 复制代码
<template>
  <!-- 使用图标,name 格式为「图标集前缀:图标名称」,比如 mdi:home -->
  <Icon :icon="name" />
</template>

<script setup>
// 导入 Iconify 的 Vue 组件
import { Icon } from '@iconify/vue'
const props = defineProps({
  name: { // 定义要使用的图标名称
    type: String,
    required: true,
  },
})
</script>

Iconify 的核心构成

Iconify 并非单一工具,而是由多个核心开源库协同构成的生态。先理清这些库的关系,才能更好理解自建 API 服务的本质:

图标源:icon-sets

仓库地址:https://github.com/iconify/icon-sets

这是 Iconify 所有图标的数据源,它以 JSON 格式汇集了 200+ 开源图标集的内容,并且会定时自动更新。这些图标并非直接照搬原图标库,而是经过了专门处理:

  • 通过 Iconify Tools(Iconify 官方的图标处理工具库)筛选和优化,剔除了脚本、事件监听器、字体、光栅图像等冗余内容。
  • 图标中的单色填充色被替换为 currentColor,你可以通过修改文本颜色直接更改图标颜色,适配性更强。
  • 图标代码被压缩优化,最大限度减小文件体积。

前端展示层:iconify

仓库地址:https://github.com/iconify/iconify

这是 Iconify 的前端核心框架,提供了各类前端框架(Vue/React/Angular 等)的图标组件,也就是在项目中用来展示图标的界面层。

后端服务层:Iconify API

仓库地址:https://github.com/iconify/api

这是为前端提供图标数据的后台服务,也是本次自建部署的核心对象 。前端组件会通过请求 API 来获取 icon-sets 中的图标数据。

构建 Iconfy API 服务

官方原本在 Docker Hub 提供了 Iconify API 的镜像(地址:iconify/api),理论上可以直接拉取镜像部署。但实际测试发现,国内 Docker Hub 镜像源并没有这个docker,国内无法直接拉取这个官方镜像 ,会出现超时错误(timeout error

因此,笔者选择通过 Iconify API 的 GitHub 仓库代码自行打包构建 Docker 镜像 ,再进行容器化部署,接下将会介绍本次部署遇到的各种问题,即对应的解决方法,笔者采用的系统是Ubuntu 24.04.3 LTS

前序准备

首先需要去 GitHub 克隆Iconify API代码,然后将代码压缩包上传到云端,在云端压缩,解压完成进入对应的目录,需要关注的文件是docker.shDockerfile

bash 复制代码
sftp username@server_ip # 建立sftp连接
put  api-main.zip api-main.zip # 上传文件 put [上传文件路径][远端路径]
apt install -y unzip # 下载解压工具
unzip api-main.zip  # 解压到当前目录
cd ./api-main

修改对应文件

由于官方给的 Dockerfile 是适配大公司的 CI 环境 / 公司内网镜像,因此构建镜像过程出现了很多问题,下面是需要修改的东西:

dockerfile 复制代码
# 注释掉这三行
RUN cp /etc/apt/sources.list /etc/apt/sources.list.original
RUN ([ -s /tmp/sources.list.tmp ] && mv -f /tmp/sources.list.tmp /etc/apt/sources.list && cat /etc/apt/sources.list) || (cat /etc/apt/sources.list)
COPY tmp/build-ca-cert.crt /usr/local/share/ca-certificates/build-ca-cert.crt
# 删除
# Restore the original sources.list
    ([ -s /etc/apt/sources.list.original ] && mv /etc/apt/sources.list.original /etc/apt/sources.list) && \
    # Remove the temporary build CA cert
    rm -f /usr/local/share/ca-certificates/build-ca-cert.crt

如果你不想修改,可以通过ls -l 去判断自己系统内是否具有/etc/apt/sources.list & tmp/build-ca-cert.crt 这两个文件,即使存在,也需要判断大小是否为 0,为 0 也不行。

dockerfile 复制代码
# 加速 apt
# 新增 阿里云 Debian Bullseye 源
RUN sed -i 's|deb.debian.org|mirrors.aliyun.com|g' /etc/apt/sources.list && \
    sed -i 's|security.debian.org|mirrors.aliyun.com/debian-security|g' /etc/apt/sources.list
    
# 修改 RUN set -ex 行命令
# rm -rf /tmp/* && \ 替换为 
rm -rf /var/lib/apt/lists/*

构建镜像

在修改对应文件后,在当前目录下执行:sh ./docker.sh 这里也可以不加 sh 如果没有报 -bash: ./docker.sh: Permission denied错误的话。

bash 复制代码
# 检查镜像
docker image ls
# 出现下面两个镜像即构建成功
iconify/api            3.2.0 
iconify/api            latest

部署镜像

笔者是通过docker compose进行部署的,如果不想采用这个方案,可以将我下面提供的docker-compose.yml进行转化为对应的docker run命令

yaml 复制代码
# docker-compose.yml
version: '3.9'
services:
  iconify-api:
    image: iconify/api:latest
    container_name: iconify-api
    restart: always  # 容器故障自动重启
    ports:
      - "3000:3000"   # 映射端口(宿主机:容器内)
    environment:
      # - ICONIFY_SOURCE=none  # 禁用官方图标源
      - HOST=0.0.0.0
      - PORT=3000
      # 性能优化:禁用不需要的功能(根据需求调整)
      # - ENABLE_ICON_LISTS=false  # 仅提供图标数据,不提供列表接口
      # - ENABLE_SEARCH_ENGINE=false  # 禁用搜索功能(节省内存)
      - NODE_ENV=production  # 生产环境标识
    volumes:
      # 挂载自定义图标集目录(本地图标集放在宿主机 ./icons 目录)
      - /home/iconify/custom-icons:/data/iconify-api/icons:ro  # ro=只读,防止容器内误修改
      # 挂载缓存目录(持久化图标缓存,避免重启后重新加载)
      - /home/iconify/iconify-cache:/data/iconify-api/cache
    logging:
      driver: "json-file"
      options:
        max-size: "5m"    # 单个日志文件最大10MB
        max-file: "3"      # 最多保留3个日志文件
bash 复制代码
# 没有docker compose 可以通过下面命令下载
apt install -y docker-compose-plugin # 验证 docker compose version
# 部署命令
docker compose up -d # 出现 Container iconify-api  Started 即部署成功
# 验证
docker ps # 查看对应的docker有没有运行
docker logs iconify-api # 查看运行日志是否报错
# 记得开启ufw端口
# 外部请求
curl http://<ip>:3000/material-symbols.json?icons=database-search-outline

前端切换请求源

还是以 Vue为例子,只需要在main.ts(Vue 挂载的入口文件)中添加如下代码:

js 复制代码
// 采用自定义iconfy API 服务器地址
import { addAPIProvider } from '@iconify/vue'
addAPIProvider('', {
  resources: ['http:xxx:3000' || 'https://api.iconify.design'],
})

''指代默认请求地址,除此外还可以指定con集请求源地址,详细内容请看文档https://iconify.design/docs/api/providers.html

扩展源码讲解

这个部分,笔者将简要讲解一下 iconify-api代码的扩展使用。

  • api/icons/ 目录:存放自定义图标集(IconifyJSON 格式,可参考 icon-set 仓库内的 json 目录下的 json 文件)。
  • src/config/icon-sets.ts:配置图标集来源(决定是否加载自定义图标)。

图标集加载流程: src/config/icon-sets.tsgetImporters 函数定义图标来源,优先加载 icons/ 目录的自定义图标。若 ICONIFY_SOURCE=none,则仅加载 icons/ 目录下的图标集。

看过代码发现,其实在 API 的代码里并没有直接存放图标集 ,而是在服务启动时或更新时从指定源下载并本地存储 (缓存数据默认存储在容器内/data/iconify-api/cache下面),之后所有请求都从本地服务获取,无需依赖外部链接。(详见src/config/importers/该目录下对应不同ICONIFY_SOURCE配置有不同的加载方式,默认是full)

相关推荐
没事别瞎琢磨几秒前
三、配置系统——默认值与解析
人工智能·node.js
ssshooter3 分钟前
为什么父元素的高度不会包含子元素的 margin?
前端·javascript·面试
静Yu10 分钟前
从一个九宫格素材小程序,看轻量工具产品该如何优化体验
前端·微信小程序
程序员黑豆22 分钟前
AI全栈开发之Java:第一个Java程序
前端·后端·ai编程
小Q的编程笔记27 分钟前
Pump.fun 的核心是什么?用 300 行 Solidity 实现 Bonding Curve 与自动 LP 销毁
前端·后端·智能合约
卷帘依旧28 分钟前
React Fiber机制
前端
卷帘依旧1 小时前
JavaScript 判断页面加载完成的多种场景
前端
光影少年1 小时前
React 项目常见优化方案
前端·react.js·前端框架
某林2121 小时前
Isaac Sim 5.1.0 无头服务器部署与 RTX 显存段错误排障全记录
运维·服务器·docker·容器·isaac
右耳朵猫AI1 小时前
Node.js周刊2026W22 | Node.js 26、Deno 2.8、Rolldown 1.0、TypeORM 1.0、Bun v1.3.14
node.js