☰
dansy自托管导航页简单配置:从Docker部署到YAML定制
2026/9/26 12:04:58 网站建设 项目流程

dansy 导航简单配置

做自托管导航页这件事,我前前后后折腾过不少方案。一开始用浏览器收藏夹,一百多个链接堆在书签栏里,找个工具要翻好几屏,后来换成在线导航站,又要担心隐私和访问速度。直到把 dansy 这类轻量导航页项目部署到自己服务器上,才算是把“找链接”这个问题真正解决了。

dansy 是一个典型的轻量级自托管导航/起始页项目,核心思路很简单:用一个配置文件管理所有常用链接,通过 Web 界面统一展示,还支持分组、图标、搜索、标签等常见功能。它不像某些商用导航系统那么复杂,不需要数据库,不需要独立的 Web 服务框架,部署起来非常快,适合个人使用,也适合小团队做内部常用入口。如果你是那种喜欢把自己常用的工具、文档、后台、面板都集中到一个页面里的人,dansy 基本就是为这个场景设计的。

这篇文章我就从方案选型、环境准备、配置文件编写、进阶玩法到常见问题排查,完整走一遍 dansy 的简单配置流程。内容会比较细,包括我实际踩过的坑和补救办法,尽量让你照着操作就能跑起来。

1. 为什么我选 dansy 做导航页:核心思路与方案选型

1.1 自托管导航页解决了什么痛点

很多人觉得导航页没什么技术含量,浏览器收藏夹不就够了吗。其实等链接数量一上来,问题就暴露了:收藏夹只能按时间或名称排序,没有自定义分组;换个设备、换个浏览器,书签完全不同步;团队协作时,大家各自收藏各自的,入口分散,效率很低。

自托管导航页的出现,就是把这些痛点集中解决掉。它本质上是一个部署在你可控服务器上的 Web 服务,把常用链接集中到同一个界面里,统一分类、统一搜索、统一展示。你可以把它当成个人数字工作台的首页,也可以当成团队内部知识库的入口。

dansy 在这个赛道上属于“简单但够用”的类型。我选它的理由有三个:一是部署门槛低,Docker 一条命令就能起服务;二是配置全部集中在一个 YAML 文件里,改起来直观,不怕配错后系统挂掉,大不了把配置改回来重启;三是它不依赖外部在线服务,数据都在本地,速度和隐私都有保障。

1.2 dansy 的设计思路与同类方案对比

其实市面上的自托管导航页项目不少,除了 dansy,常见的还有 Dashy、Flame、Homer、Heimdall 等。它们解决的问题一致,但设计思路差别很大。我用过一个多月 dansy,也用过其他几个,简单做个对比,方便你判断自己适合哪个。

项目配置方式是否需要数据库功能丰富度上手难度适合场景
dansyYAML 单文件不需要中等,够用非常低个人/小团队快速搭建
DashyYAML 单文件不需要很高,支持状态监控、多用户中等追求丰富功能的折腾党
Flame界面直接编辑不需要中等低喜欢可视化配置的用户
HomerYAML 单文件不需要偏低非常低极简风格爱好者
Heimdall界面直接编辑需要 SQLite中等低喜欢点选式管理的用户

说实话,dansy 在功能上不如 Dashy 丰富,比不上 Heimdall 的“所见即所得”,但它的优势恰恰在“简单配置”这四个字上。我个人的体会是,导航页这种工具,90% 的时间就是打开浏览器、点一个链接,功能太多反而容易变成新的负担。dansy 把配置逻辑收敛到单一文件,配合少量环境变量,就能实现基本所有常用能力,这对大多数场景来说已经足够。

如果你的需求更复杂,比如需要多用户权限区分、需要内置状态监控面板、需要直接编辑各种组件,那确实可以考虑 Dashy。但如果你只是想给自己或团队一个干净、快速、容易维护的导航首页,dansy 会是更省心的选择。

1.3 部署前要确认的几个前提

在动手部署 dansy 之前,有几个前提条件最好先确认清楚,避免装到一半才发现环境不对。

第一个是设备选择。dansy 对硬件几乎没有要求,一台普通 Linux 服务器、一个树莓派、甚至一台跑着 Docker 的 NAS 都可以。我自己用的是 N5105 小主机,性能很普通,但跑这个服务绰绰有余。如果是纯本机体验,Windows 上开 WSL2 装 Docker 也行。

第二个是 Docker 环境。dansy 官方最推荐的安装方式就是 Docker,因为镜像里已经包含了所有运行时依赖,不需要你在宿主机上单独装 Node.js 或 npm。只要设备上有 Docker 和 Docker Compose,部署就是几分钟的事。

第三个是端口规划。默认端口是 8080,如果这个端口已经被其他服务占用,需要在部署前就想好替代端口,否则启动会直接报错。

第四个是配置文件的位置。dansy 的配置目录在容器内对应/app/conf,你需要把宿主机的一个目录挂载进去,方便直接改文件。这个目录选择很关键,后面备份、迁移全靠它。

把这些前提理清楚之后,安装就是一条直线了。

2. 部署前的环境准备与安装步骤

2.1 准备一台能跑 Docker 的设备

这一步看似基础,其实挺多人会忽略细节。比如 Docker 装好了,但当前用户没有加入 docker 用户组,导致运行 docker 命令必须加 sudo,后面写进 systemd 服务或者自动启动脚本时就会多出权限问题。

我建议在部署前先把这几件事做掉:

  • 安装 Docker Engine 和 Docker Compose 插件。
  • 把当前用户加入 docker 组,然后重新登录终端,这样不用每次敲 sudo。
  • 确认/etc/docker/daemon.json里的镜像源配置可用,避免拉取镜像时超时。
  • 规划好数据目录,比如/opt/dansy,后续的配置、数据都放在这里。

我的习惯是统一在/opt下建一个项目目录,这样每个自托管服务都有独立空间,互不干扰。比如我现在的目录结构是这样的:

/opt/dansy ├── docker-compose.yml └── conf └── conf.yml

这个结构本身没什么特殊,但好处是迁移的时候只需打包整个/opt/dansy目录,换一台机器解压再启动,服务就回来了。

2.2 通过 docker-compose 安装 dansy

Docker 部署 dansy 的 compose 配置并不复杂,我用的是下面这个版本。先创建一个/opt/dansy/docker-compose.yml文件,内容如下:

version: "3.8" services: dansy: image: dansy/dansy:latest container_name: dansy restart: unless-stopped ports: - "8080:8080" environment: - TZ=Asia/Shanghai - DANSY_TITLE=我的导航 volumes: - /opt/dansy/conf:/app/conf

解释几个关键点:

  • ports部分,宿主机 8080 映射到容器 8080。如果你想换端口,比如本机 9000 已经给别人用了,改成"9000:8080"就行。左边的端口是宿主机端口,右边是容器内固定端口,不要改右边。
  • environment部分,TZ=Asia/Shanghai是为了解决容器默认时区 UTC 导致时间显示差 8 小时的问题。DANSY_TITLE是自定义导航页标题的环境变量,这里我先设为“我的导航”,后面也可以不改代码直接改配置。
  • volumes部分,把宿主机/opt/dansy/conf挂载到容器内/app/conf,这样导航配置在被容器使用时仍然可以直接编辑宿主机上的文件。

写完之后,在/opt/dansy目录下执行:

docker compose up -d

第一次执行会拉取镜像,需要一点时间。等它跑完,执行docker ps看一下容器状态是否正常。正常情况下应该显示Up状态,端口映射也正确。

2.3 不使用 Docker 时的 Node 运行方式

有些场景下你不能用 Docker,比如服务器上已经有 Node.js 20 以上版本,或者你想直接跑源码调试。这种情况也没有问题。dansy 是 Node.js 项目,可以直接用 npm 启动。

先确认 Node 版本:

node -v

建议 v20 以上,太老的版本会缺一些新特性的支持。然后拉源码、装依赖、启动:

git clone https://github.com/dansy/nav.git /opt/dansy-source cd /opt/dansy-source npm install npm run build npm start

这种方式适合想改源码、看实现细节的读者。我自己调试某个图标显示问题时就是用这种方式跑起的,方便加日志看报错。日常稳定使用的话,还是 Docker 更省心,升级也方便,只需重新拉镜像再重建容器。

2.4 验证服务是否正常启动

启动完之后,在浏览器访问http://服务器IP:8080。如果一切正常,你会看到一个默认导航页面,上面可能只有一些示例分组和示例链接。

这里有个细节值得注意:首次启动时,dansy 会在挂载的 conf 目录下自动生成一个默认配置模板。这个模板文件就是后续所有配置的起点,你可以在它基础上改,也可以直接推倒重写。

我遇到过一种情况,首次访问时页面是空的,没有默认示例,那是因为我的 compose 里指定了一个空的配置文件,而 dansy 检测到已有文件后不会覆盖它。解决办法很简单,先把空的 conf.yml 清理掉,重启容器,让服务重新生成模板。以后再想重置配置,同样思路:备份后删除 conf.yml,重启即可。

3. 配置文件编写要点与实操示例

3.1 理解 dansy 的配置结构

dansy 的配置全部集中在conf/conf.yml中,这个文件结构并不复杂,核心就是三个部分:页面信息、导航分组、分组下的具体链接。

一个大致的结构长这样:

pageInfo: title: 我的导航 appConfig: theme: light searchEngine: bing sections: - name: 常用工具 items: - name: GitHub desc: 代码托管平台 url: https://github.com icon: https://github.com/favicon.ico
  • pageInfo控制页面基本属性,比如标题栏文字。
  • appConfig控制界面行为,比如主题色、默认搜索框使用的搜索引擎。
  • sections是一个数组,每个元素是一个分组,分组下面有items数组,每个 item 就是一条导航链接。

刚开始接触 YAML 的读者可能会犯一个很基本的错误:缩进搞混。YAML 对缩进非常敏感,items必须缩进在- name: 常用工具的下一级,否则解析直接报错。我建议在编辑器里统一使用两个空格缩进,不要用 Tab,也不要混用。

3.2 写一个完整的导航分组示例

下面这份配置是我自己服务器上实际在用的简化版,覆盖了几个常用场景:技术开发、运维监控、影音娱乐、日常搜索。

pageInfo: title: 我的工作台 appConfig: theme: dark showTags: true searchEngine: google sections: - name: 日常搜索 items: - name: Google desc: 搜索 url: https://www.google.com icon: https://www.google.com/favicon.ico - name: Bing desc: 微软搜索 url: https://www.bing.com icon: https://www.bing.com/favicon.ico - name: 技术开发 items: - name: GitHub desc: 代码托管与开源社区 url: https://github.com icon: https://github.com/favicon.ico - name: 本地服务 desc: 开发环境入口 url: http://192.168.1.100:3000 icon: https://nodejs.org/favicon.ico - name: NPM desc: 包管理平台 url: https://www.npmjs.com icon: https://www.npmjs.com/favicon.ico - name: 运维观测 items: - name: Grafana desc: 监控看板 url: http://grafana.local:3000 icon: https://grafana.com/favicon.ico - name: Portainer desc: Docker管理面板 url: http://192.168.1.100:9000 icon: https://www.portainer.io/favicon.ico - name: 影音娱乐 items: - name: YouTube desc: 视频网站 url: https://www.youtube.com icon: https://www.youtube.com/favicon.ico - name: 音乐站 desc: 在线音乐 url: https://music.example.com icon: https://music.example.com/favicon.ico

配置写好之后,在/opt/dansy下执行:

docker compose restart

重启过后刷新页面,就能看到分组和链接按你定义的顺序展示出来了。

这里解释一下google和bing两个链接为什么都要加上:appConfig.searchEngine控制的是页面自带搜索框的默认引擎,而日常搜索分组里的链接是直接点击跳转用的,两个是不同维度,可以同时保留。

3.3 图标、标签、快捷键等细节怎么配

链接能不能一眼认出来,图标很关键。dansy 的icon字段支持三种写法:

  • 外链图标地址,比如https://github.com/favicon.ico。
  • 本地静态文件路径,比如/icons/github.png,需要你把图片放到容器能访问到的静态目录里。
  • Base64 内嵌的 data URI,data:image/png;base64,xxxx。这种方式适合不稳定外链的图标,但会让配置文件变得很长,不推荐大量使用。

我实际用下来发现,favicon.ico 是最省事的选择,大部分知名网站都有稳定地址。但有个坑是某些网站做了防盗链,导致图标在导航页上显示不出来。遇到这种情况,我的处理办法是把图标下载到本地,用方式二解决。

tags是另一个细粒度管理手段。给一条链接打上多个标签后,页面上的分组可以按标签过滤。比如:

- name: 个人博客 url: https://blog.example.com icon: https://blog.example.com/favicon.ico tags: - 写作 - 前端

这样在分组内可以通过标签快速筛选,而不必为了一个链接建一个新分组。

快捷键方面,dansy 的分组定义里可以设置一个按键,比如用key: g给某个分组绑定字母键。实际使用时,键盘输入g,该分组会自动展开或高亮,对于链接特别多的场景可以省不少鼠标操作。

3.4 配置热更新与校验技巧

改配置最怕的是改完发现 YAML 语法错了,页面直接打不开。为了避免这种情况,我提供一个笨但有效的方法:改配置前先复制一份备份,改完用 Python 做语法校验。

pip install pyyaml python3 -c "import yaml,sys; yaml.safe_load(open('/opt/dansy/conf/conf.yml')); print('OK')"

如果输出OK,说明语法没有大问题,可以放心重启。如果报错,会直接提示哪一行有问题,比如mapping values are not allowed here,那就说明你在key: value里漏了空格或者多打了字符。

关于热更新,dansy 支持通过 API 或信号触发配置重载。最简单的操作方式是先备份配置,再执行容器重启。重启本身消耗时间不超过几秒,对于导航页这种低频工具来说完全可接受。

我会在配置里先备份一份conf.yml.bak,每次大改之前覆盖一次,想回滚就一条命令把备份拷回来:

cp conf.yml.bak conf.yml

这个习惯帮我避免了好几次配置改坏后靠记忆恢复的窘境。

4. 进阶玩法:域名访问、HTTPS 反代与多端适配

4.1 用 Nginx 反代绑定域名

导航页本身用 IP 加端口访问没问题,但每次都敲一串 IP 和端口总归不够体面。如果你有自己的域名,可以加一层反向代理,把它转发到一个子路径或子域名上。

我用 Nginx 做反代的配置大致如下,假设你有一个域名nav.example.com:

server { listen 80; server_name nav.example.com; location / { proxy_pass http://127.0.0.1:8080; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto $scheme; } }

这段配置放在/etc/nginx/conf.d/dansy.conf里,配置好之后用nginx -t检查语法,再执行systemctl reload nginx即可。

如果你懒得装 Nginx,也可以直接用 Caddy,配置更短。一个Caddyfile几行就搞定:

nav.example.com { reverse_proxy 127.0.0.1:8080 }

Caddy 还会自动申请和续期 HTTPS 证书,省去自己折腾证书的麻烦。对有域名的场景,这是最省心的方案。

4.2 移动端与桌面端的显示适配经验

dansy 默认界面是响应式设计,手机浏览器上打开会自动变成单列布局。但实际体验中,分组的顺序在手机上显得比较长,容易滑好几屏才能找到目标。

我自己的处理方式是根据使用习惯调整分组顺序:桌面端主力访问的放前面,手机端频繁用的放前面。这类导航页服务的共同特性是“越简单越好用”,不需要为移动端单独做一套界面,把最重要的分组放前面就是最实用的适配。

如果团队内有人使用平板或者大屏设备,可以在appConfig里设置默认主题为深色,以及开启栅格密度选项,大屏上显示的信息密度会更高,一屏能看到更多链接。

4.3 状态监控与搜索功能扩展

dansy 自带一个比较实用的功能:内置状态检测。它可以配置某些链接为可监控目标,定时向目标地址发送请求,检测服务是否在线,然后在导航页上显示在线/离线状态。这个功能适合自托管服务比较多的人,比如我把自己服务器上的 Grafana、Portainer、几个内网工具加进去,一眼就能看到哪些服务出问题了。

配置方式是在对应 item 上加一个字段:

- name: Grafana url: http://grafana.local:3000 icon: https://grafana.com/favicon.ico statusCheck: true

开启之后,导航页会在后台异步检查这些目标的连通性,并根据结果显示状态圆点。这里有一个需要注意的点:如果监控目标是内网地址,而 dansy 部署在公网服务器上,那它检测不到内网服务,状态会一直显示离线,会有误导性。这种情况建议要么把 dansy 部署在内网,要么就不要对这些内网地址开启状态检测。

搜索功能方面,除了页面自带的搜索框可以切换搜索引擎之外,还可以给每个链接设置搜索关键字。比如给“百度搜索”配置一个别名bd,之后在页面的地址栏输入bd dansy这种方式并不支持,实际可用的方式是页面搜索框会先搜索本地链接名称,再跳转到搜索引擎。简单说,导航页的“搜索”能力更侧重于快速检索本地链接,而不是替代搜索引擎。

5. 常见问题与排查实录

5.1 配置改了不生效,怎么办

这个问题出现的频率最高。配置改了,重启了容器,页面刷新还是老样子。我刚开始也遇到过一次,排查下来通常是这几种原因。

第一种是配置路径挂载错了。确认宿主机上修改的文件确实挂载到了容器内/app/conf/conf.yml。可以执行docker exec dansy cat /app/conf/conf.yml看容器里读取到的内容和宿主机上是否一致。如果不一致,就是 volume 路径写错,容器没读到宿主机上的文件。

第二种是 YAML 语法解析成功了,但字段名写错。dansy 对未知字段不会立即报错,它只会默默忽略,导致看起来像“配置没生效”。这时候建议对照项目默认配置模板,一个字段一个字段核对。

第三种是浏览器缓存。页面和静态资源被浏览器缓存了,刷新不一定能拿到最新内容。解决办法很简单:快捷键强制刷新(Windows 下Ctrl + F5,Mac 下Cmd + Shift + R),或者开一次无痕窗口验证。

5.2 图标显示异常的处理思路

图标问题也是高频问题。我会按下面这个顺序排查:

  • 先检查外链地址是否可以直接访问。直接复制图标 URL 到浏览器打开,能显示再回到导航页看。
  • 如果浏览器能打开但导航页不显示,基本就是防盗链问题。解决办法是把图标图片下载到本地静态目录,改成本地路径引用。
  • 如果本地路径也不显示,检查文件权限和格式。容器内的用户需要能读到/app/conf下的文件,一般权限设为 644 就够了。
  • 有些站点没有 favicon,这时候可以尝试用https://www.google.com/s2/favicons?domain=example.com这类第三方图标服务生成图标。这类服务稳定性和隐私都有一定不确定性,需要自己权衡。

5.3 端口占用、时区错误、容器内权限问题

端口占用是 Docker 启动失败里最常见的报错,典型提示是Error response from daemon: driver failed programming external connectivity。排查方法很简单:

sudo ss -tlnp | grep 8080

如果输出显示端口已被占用,要么停掉旧服务,要么就把 dansy 的宿主机端口改成其他值。

时区问题在导航页上表现为“最近更新”“状态检测时间”等时间显示比本地时间慢 8 小时。解决方式就是在environment里设置TZ=Asia/Shanghai,然后重建容器让环境变量生效。注意单纯执行docker compose restart不一定能让新环境变量生效,因为容器没有重建,一般来说需要执行docker compose up -d让 compose 检测到配置变更后自动重建。

权限问题往往出现在手动往 conf 目录里放文件的时候。如果你下载的图片、配置模板是从别的机器拷来的,文件属主和宿主机用户不一致,容器内读取就会报权限不足。处理方法是直接改属主:

sudo chown -R 1000:1000 /opt/dansy/conf

容器默认用户一般有固定的 uid,设为1000:1000是最常见的做法,具体以项目文档为准。

5.4 备份与迁移 dansy 配置

导航配置文件属于“小数据大价值”,丢一次就非常麻烦。我的备份策略非常简单:定时打包 conf 目录。

tar czf dansy-backup-$(date +%Y%m%d).tar.gz /opt/dansy/conf

把这个打包结果传到对象存储、网盘或另一台机器上,需要恢复的时候解压到新的宿主机对应目录,再按原来的 compose 配置启动容器,导航页就回来了。

迁移的时候有个容易忽略的细节:如果新机器的端口规划不同,或者网络环境不同,要先改好 compose 里的端口映射和 HTTPS 反代配置,再启动容器。否则旧配置里的内网链接在新设备上会一直打不开,容易误判成配置迁移失败。

另外,如果你的导航页里存了一些内部系统地址或者内网服务链接,迁移时要确认新环境的 DNS 解析规则是否一致,否则外部访问环境下那些内网地址也访问不通。这个通常和 dansy 本身无关,但恰恰是自托管服务迁移时最容易被忽略的问题。

5.5 自定义修改的常见误区

最后聊一个很多人会掉进去的误区:为了某个小功能去改源码。

dansy 的配置体系已经覆盖了大部分使用场景,但有些东西是配置里改不了的,比如页面某些布局细节、个别交互逻辑。有人会直接改前端代码,结果下一次拉新镜像,代码全被覆盖,改动全丢。如果确实需要深度定制,我的建议是先把需求具体化,评估在现有配置体系里是否能绕过去。能绕过去的尽量绕,不能绕过去的再考虑 fork 代码,把定制修改与镜像升级流程捆绑起来。

我自己也做过一次小改,加了一个自定义分组折叠功能。做法是 fork 项目,改完前端代码重新打包镜像,日常稳定运行没问题,但代价是每次官方升级都要手动合并一次代码。如果你的需求没有那么强,真的不建议走这一步。

写在最后的一点个人体会

dansy 这类轻量导航页项目,最大的价值不是功能有多全,而是把“找链接”这件琐事变得非常顺滑。我自己用了段时间之后,已经养成了每天开浏览器的第一件事就是打开导航页的习惯,工具、文档、监控面板全在一个页面里,省了不少来回切换的时间。

如果你也和我一样,曾经在收藏夹里翻了半天找不到一个常用链接,或者被一堆浏览器书签搞得心烦,不妨花半个小时把 dansy 跑起来试试。先从最简单的分组开始,把你最高频的 10 个链接放进去,用一段时间你就会发现,这种简单的自托管方案,反而是最不容易吃灰的那类工具。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询