Featured image of post 手把手教你打造一个漂亮的导航页面

手把手教你打造一个漂亮的导航页面

背景

如果你像我一样有一个HomeLab,有多台机器和一些服务,为了方便跳转和统一管理,有可能已经尝试过一些导航页如homepage或好看点的heimdall。除此之外我还试过flare,一个轻量高效的bookmark管理。但这些或多或少缺少一些我期待的能力,直到我遇到dashy

需求

可能除了基本的bookmark外,你还想有:

  • 页面状态展示,当不可用时,可以发现。
  • 一些小组件,可以查看如时间,天气等,提供扩展性。
  • 可聚合一些外部指标,方便一站式观测。比如下载进度,NAS IO等。

在无意之中发现Dashy后,详细研究了一下它的文档,打造了如下的一个Dashboard,用于展示它的一些能力: dashy dashboard

以上页面除了一些标准的链接外,还集成了uptime-kuma,从中获取一些状态探测的数据。集成了glances提供的数据,可实时看到机器的各种数据。集成了grafana的图表,方便利用现有的视图。另外,因Dashy支持多pages,这块也测试了一下,可以看到上图右上角有子页面。

如何做到这些,下文我将一一道来,有一些坑或小技巧,或许能帮你减少几小时折腾时间。

基本使用

部署dashy

你可以使用多种方式部署它,以下是我基于docker-compose部署的清单:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
version: "3.8"
services:
  dashy:
    # To build from source, replace 'image: lissy93/dashy' with 'build: .'
    # build: .
    image: lissy93/dashy
    container_name: Dashy
    # Pass in your config file below, by specifying the path on your host machine
    volumes:
      - /var/services/homes/kevin/Apps/Dashy/conf.yml:/app/public/conf.yml
      - /var/services/homes/kevin/Apps/Dashy/ds920.yml:/app/public/ds920.yml
    ports:
      - 4000:80
    # Set any environmental variables
    environment:
      - NODE_ENV=production
    # Specify your user ID and group ID. You can find this by running `id -u` and `id -g`
      - UID=1026
      - GID=100
    # Specify restart policy
    restart: unless-stopped
    # Configure healthchecks
    healthcheck:
      test: ['CMD', 'node', '/app/services/healthcheck']
      interval: 1m30s
      timeout: 10s
      retries: 3
      start_period: 40s

主要修改的是上面conf.yml的挂载(有多个页面就如上面挂载多个yaml文件)。

Bookmark功能

这个很简单,参考官方文档即可,比如在conf.yml中这样定义:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
sections:
  - name: 主要服务器(内网连接)
    icon: far fa-rocket
    items:
      - title: HP66
        description: PVE
        icon: hl-proxmox
        url: "https://192.168.50.250:8006/#v1:0:18:4:::::::"
        target: newtab
        statusCheck: true
        statusCheckAllowInsecure: true
        id: 0_371260_hp

上面section定义了一个段(UI中的一列),里面可以放各种item或widget。要多说一句的是,dashy内可以使用很多很棒的资源作图标,比如使用Simple Icons,你只要在填写图标时写si-proxmox即会当场获得一个PVE的图标。还有更漂亮的Home-Lab Icons,类似的hl-proxmox会获得一个漂亮的PVE图标。你对当前提供了哪些图标好奇可直接访问这里

Widgets功能

小组件挺多的,有一些实用的如天气/时钟等,你可以很简单的集成到dashboard中。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
  - name: 实时动态
    icon: hl-apache-openoffice
    widgets:
      - type: clock
        options:
          timeZone: Asia/Shanghai
          format: en-GB
          hideDate: false
          customCityName: Shenzhen
      - type: weather
        options:
            apiKey: <你自己的weather apikey>
            city: Shenzhen
            units: metric
            hideDetails: false

还有iframe和embed等功能,带来了不少可能性。比如我们可以给页面添加一个测速组件。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
- type: embed
  options:
    scriptSrc: https://cdn.speedcheck.org/basic/scbjs.min.js
    html: |
      <div id="sc-container">
      <div id="sc-branding" class="sc-bb">
      <a target="_blank" href="https://www.speedcheck.org/">
      <img src="https://cdn.speedcheck.org/branding/speedcheck-logo-18.png" alt="Speedcheck"/>
      </a>
      </div>
      </div>      

高阶玩法

官方的Widget中提到未来可能会有Prometheus相关Widgets,也可能会有API Response,可惜当前都没支持。

Tip

API Response# Directly output plain-text response from any API-enabled service.

// Coming soon…

Prometheus Data# Display data from any service with a Prometheus exporter.

// Coming soon…

但正如前文所说,iframe已经提供了很多可能性了。

将uptime-kuma整合

术业有专攻,如果你想找个Widget实现各种类型的探测,你仔细看后发现只有简单的一些http探测,想DNS,ping等都是比较困难的,但这事uptime-kuma就很擅长呀:) 见下图: uptime-kuma functions 我个人用它监控几年了,感觉UI和功能都还不错。我们可以将它整合到你的Dashboard来,可以一目了然的看到关键信息。为此我们可以为dashy定制一个状态页面,隐藏掉一些标题或不必要的内容,让内嵌页面呈现比较干净。可以在定制页面时,在“自定义CSS”中设置如下:

1
2
3
4
5
6
7
8
body {
.overall-status {
  display: none;
  }
.mb-4.title-flex {
   display: none;
   }
}

具体要隐藏哪些组件,可以借助浏览器的开发者工具,查看到相关不想要的地方的css,将其display: none;即可。会看到类似这样比较干净的页面: uptime-kuma for dashy 然后我们就可以尝试在dashy中通过iframe引用它了。

1
2
3
4
5
6
    widgets:
      - type: iframe
        options:
          url: https://status.mrlin.cc/status/embed-by-dashy
          frameHeight: 400
        id: 0_2071_iframe

结果你发现还是不行,内嵌的页面中提示“连接拒绝”。查看这里可以看到:

By default, Uptime Kuma is not allowed in iframe if the domain name is not the same as the parent. It protects your Uptime Kuma to be a phishing website. If you don’t need this protection, you can set it to true.

只要给你的uptime-kuma添加环境变量,类似如下:

1
2
    environment:
      UPTIME_KUMA_DISABLE_FRAME_SAMEORIGIN: "true"

这样即可正确的将uptime-kuma集成进去啦。

将glances整合

Dashy有不少widgets基于glances,glances是一个很棒的资源监控面版,它还有一个web UI。在Ubuntu中应该借助包管理器安装即可,如果你想监控你的群晖等类似系统,也可以借助容器来部署glances服务。可以参考这篇文章

1
2
3
4
5
6
7
docker run -d --name=glances \
-p 61208:61208 \
-v /var/run/docker.sock:/var/run/docker.sock:ro \
-e GLANCES_OPT=-w \
--restart always \
--pid=host \
nicolargo/glances:latest-full

然后你就可以使用这些组件:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
  - name: 实时监控(glances)
    icon: hl-apache-openoffice
    widgets:
      - type: gl-cpu-history
        options:
            hostname: http://192.168.50.55:61208
            limit: 60
      - type: gl-network-traffic
        options:
            hostname: http://192.168.50.55:61208

将grafana整合

作为一个非常通用的标准,整合grafana是一个很有用的场景。为了将grafana中的视图整合进来,我们要解决两个问题。一个是类似uptime-kuma一样的,默认都是不允许embed的,需要设置GF_SECURITY_ALLOW_EMBEDDINGtrue才可以。同时,一般情况下我们grafana会要求鉴权,我们要设置可匿名访问。这块修改的目标是grafana.ini里的一些设置。如果你和我一样是使用helm部署prometheus和grafana的话,以下是参考的几个配置:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
grafana:
  enabled: true
  defaultDashboardsTimezone: Asia/Shanghai

  # 没有这个,不让embed
  env:
    GF_SECURITY_ALLOW_EMBEDDING: "true"

  grafana.ini:
    server:
      domain: "https://grafana.mrlin.cc"
      root_url: "https://grafana.mrlin.cc"
    # 没有这个,还要你鉴权
    auth.anonymous:
      enabled: true
      org_name: Main Org.
      org_role: Viewer

然后我们可以在grafana中找到想被嵌入的panel,点击Share,选择Link,拷贝对应的Link URL后,填到iframe中,大概如下:

1
2
3
4
5
6
7
8
9
  - name: 实时监控(grafana)
    icon: hl-grafana
    widgets:
        - type: iframe
          options:
            url: >-
                https://grafana.mrlin.cc/d/rYdddlPWk/node-exporter-full?orgId=1&refresh=1m&viewPanel=136&kiosk                
            frameHeight: 200
            id: 0_775_iframe

同样的,为了使得嵌入的面板更加干净,请确保你拷贝的 iframe 代码中的 URL后添加 &kiosk 参数,这可以隐藏 Grafana 的用户界面元素。现在,你可以借力grafana将更多有价值的视图整合到Dashy面板啦。

多页显示

在Dashy中的配置指出了其支持多页显示,我在尝试过程中遇到了一点小坑,假如你有两个页面要显示,你可以这样配置默认conf.yml文件。

1
2
3
pages:
- name: DS920
  path: "ds920.yml"

这里直接写文件名下,要求你将对应的yaml文件(另一个页面的配置文件,和conf.yml是一样的结构)放到/public目录下(这也是conf.yaml默认的路径),这点见本文最上面的docker-compose文件。

然后你要配置appConfig,添加routingModehash

1
2
3
appConfig:
  language: cn
  routingMode: hash

你会发现还是不行,为啥没重效,能看到右上角的DS920但是点击无跳转,甚至重启容器也不行。解决方案是进入容器执行:

1
yarn build-and-start

静等一会(大概1-2min)就会发现终于可以跳转了。然后你尝试修改ds920.yml文件,发现它又不会跟随修改而变化,难不成每次修改要重复build-and-start?!

是的,暂时我还没找到别的办法,如果你知道原因,请一定告诉我。但是我们有一条变通的路,可以将要调试的页面先改为名conf.yml(旧文件记得备份),似乎内部会自动构建和刷新它(比较快),等调试完成才再改回目标文件名。

后记

Dashy不光UI特别酷,功能也比较丰富,目前来说还是比较满意的。不足之处是几个期待的功能还需要继续等待,好像社区也不是太活跃,上一个版本是2022年的:( 同时多页面的支持上有点瑕疵,或许等我有空,再深度研究寻找一下解决方案。

整体上,我当前还是很满意的。最近在考虑把公司的项目组首页换成它,那必然能让人眼前一亮。但,又会有一堆权限问题,试试看呗:)

参考资料