2026-05-29 15:20:00
在 Linux + Wayland 环境下使用 Joplin 时,如果配合 fcitx5 输入中文,可能会遇到输入漏字的问题。
下面这份配置可作为参考:
“`diff
➜ Downloads cat /usr/share/applications/joplin-desktop.desktop
[Desktop Entry]
Name=Joplin
Comment=Joplin for Desktop
-Exec=/usr/bin/joplin-desktop –gtk-version=3 –ozone-platform=x11
+Exec=/usr/bin/joplin-desktop –gtk-version=3 –ozone-platform-hint=auto –enable-wayland-ime
Terminal=false
Icon=joplin-desktop
StartupWMClass=@joplin/app-desktop
Type=Application
Categories=Office;
MimeType=x-scheme-handler/joplin;
SingleMainWindow=true
“`
使用 `–ozone-platform=x11` 可以解决 Joplin 全局菜单不显示的问题,但中文输入时可能会出现漏字。
改用 `–ozone-platform-hint=auto –enable-wayland-ime` 后,可以解决 fcitx5 中文输入漏字的问题;不过相应地,Joplin 全局菜单可能又无法正常显示。
实测二者不可两全,暂无找到很好的方法。建议先采用第一行配置,显示出来菜单做好配置后,改用第二行配置,确保后期中文输入体现。
输入漏字真的很恼火,如有两全解决方案欢迎讨论。
## Refs
– [Joplin can not use fcitx ime when I use wayland](https://github.com/laurent22/joplin/issues/10345)
2026-05-12 05:56:06
在 KDE 桌面下默认使用全局菜单显示应用程序的菜单栏,但是唯独 Joplin 无法显示。
最后在这里找到了解决方案,下面简单记录:
“`
sudo vim /usr/share/applications/joplin-desktop.desktop
“`
“`diff
–Exec=/usr/bin/joplin-desktop
++Exec=/usr/bin/joplin-desktop –gtk-version=3 –ozone-platform=x11
“`
启动程序增加这两个参数即可解决。
## Refs
– ArchLinux Wiki: Electron
– Menu bar lost on Manjaro Linux #14126
我的博客即将同步至腾讯云开发者社区,邀请大家一同入驻:https://cloud.tencent.com/developer/support-plan?invite_code=21yjpwt8mhhc0
2026-05-07 22:00:00
从开始工作,就一直想开发一款面向个人的财务管理软件,用来直观的分析自己的财务状况,对个人财务情况提供直观的反馈,帮助自己更好的存钱、消费和投资。获取正向反馈,激励自己更好的存钱。
此前,基于 Notion 制作过一套个人财务管理模版,取名 BJ-PFD , 是一长串英文的缩写:Bullet Journal – Personal Finance Dashboard,意为子弹笔记个人财务仪表盘。之前写过一系列的 [文章](https://frytea.com/archives/1133/) 介绍这套模版。这套模版我个人也一直在用,从2020年到2026年,已经使用了6年了,积累了大量的财务数据,帮助我更好的分析和管理个人财务状况。数据条数也增加到好几千条。此时我发现 Notion 的一些弊端暴露出来了。比如,数据库数量大了以后,加载会比较慢,而且一些数据关联会有极小概率出现问题,导致最终的数据统计出现细微的差错。更重要的一个问题,随着我数据的变多,基于 Notion API 开发的看板工具,启动速度越来越慢了,每次统计数据都要花费数分钟来加载数据。
最近,结合自己之前的工作流和数据模型,使用 AI 辅助编程开发了这款软件。经过一段时间的调试和打磨,这款软件已经能够完美承载我个人目前的财务管理需求,我也将 Notion 中的数千条数据,顺利导入这款新的软件中,数据统计速度从1分钟以上,提升到了1秒以内。现在我已经完全迁移到这款软件上了,使用体验非常好。现在,我希望将这款软件发布出来,分享给更多有需要的人使用。
下面是关于这款软件的介绍:
## Rivulet 简介
溪流记账(Rivulet)是一款极简但强大的个人财务管理软件,支持快速记录收支、多账户、多账本与共享账本;提供预算管理、投资记录与财务分析。
Rivulet 使用 GO 和 Svelte 开发,使用 Docker 封装并公开发布,支持 SQLite 和 PostgreSQL 数据库。
更多信息,可以进入 Rivulet 的 [官网](https://rivulet.app/) 或 [GitHub Docs仓库](https://github.com/songtianlun/rivulet-docs) 查看,如果有问题可以直接在 [留言板](https://rivulet.app/zh/guestbook/) 或是 GitHub Docs 仓库的 [Issues](https://github.com/songtianlun/rivulet-docs/issues)/[Discussions](https://github.com/songtianlun/rivulet-docs/discussions) 提出。
## Rivulet 功能介绍
– 支持灵活的流水管理功能,区分支出、收入和转账,并支持灵活的分类,可以方便的进行流水统计;
– 支持财务规划功能,在财务规划界面可以方便的进行每月收入、支出的预算规划,并查看实时的预算执行情况;
– 支持投资管理,提供方便的投资买入、卖出、分红记录,投资记录自动生成流水记录,并提供投资盈亏分析;
– 支持账户管理,方便关联自己实际的各个账户;
– 支持多账本,账本间的流水互相隔离,适合不同的使用场景,比如个人账本、家庭账本、公司账本等;支持账本共享。
– 更多功能陆续开发中。
## Rivulet 截图







最后,欢迎大家试用这款软件,如果有任何疑问随时与我交流,也欢迎大家提出宝贵的意见和建议,帮助我一起把这款软件做得更好。
## Refs
– [Rivulet 官网](https://rivulet.app/)
– [Rivulet GitHub Docs 仓库](https://github.com/songtianlun/rivulet-docs)
2026-04-30 08:00:00
最近爆出一个 Linux 内核存在近10年的漏洞,随便找了一台最近在用的机器试了一下,直接成功提权:
“`bash
~$ whoami
songtianlun
~$ python3 test.py
# whoami
root
“`
临时解决方案如下:
> 由于 SSH/OpenSSL 等安全基建库几乎都在使用自行维护的用户态加密库, 所以 AF_ALG 可以直接禁用, 为临时缓解措施 (仅供参考):
“`
rmmod algif_aead 2>/dev/null || true
echo “install algif_aead /bin/false” > /etc/modprobe.d/disable-algif.conf
“`
再尝试就不行了:
“`
~$ python3 test.py Traceback (most recent call last):
File “/home/songtianlun/test.py”, line 9, in
while i
2026-04-27 16:00:00
> 本文基于官方 Docker 文档,将 Hermes Agent 迁移到 Kubernetes / K3s 环境,使用 StatefulSet 管理持久化工作负载。
## 1. 前置准备
– K3s 或 K8s 集群已就绪(本文以 K3s 为例)
– 节点上已有 containerd(K3s 默认内置)
– 推荐安装 `nerdctl` 作为容器管理工具(参考:[在 K3s 节点上安装并使用 nerdctl](https://frytea.com/archives/1661/))
– 镜像:`nousresearch/hermes-agent:latest`
## 2. 初始化配置(持久化数据目录)
在首次运行前,需要先执行一次 Setup Wizard,将 API Keys 等配置写入宿主机目录,再挂载进容器使用。
> 这里建议使用 [`nerdctl`](https://frytea.com/archives/1661/) 运行,其他的方法需自行探索。
“`bash
# 在目标节点上创建数据目录
mkdir -p /var/lib/hermes-data
# 使用 nerdctl 运行一次性 setup 容器(交互模式)
sudo nerdctl run -it –rm \
-v /var/lib/hermes-data:/opt/data \
nousresearch/hermes-agent:latest setup
“`
配置完成后的数据目录结构
“`
/var/lib/hermes-data/
├── .env # API Keys 与密钥
├── config.yaml # 主配置文件
├── SOUL.md # Agent 人格 / 身份设定
├── sessions/ # 会话历史
├── memories/ # 持久记忆
├── skills/ # 已安装的技能
├── cron/ # 定时任务定义
├── hooks/ # 事件钩子
├── logs/ # 运行日志
└── skins/ # 自定义 CLI 皮肤
“`
## 3. 部署 Gateway 后台服务(StatefulSet)
这里直接给出参考 yaml,按需调整:
“`yaml
—
apiVersion: v1
kind: Service
metadata:
name: gateway
namespace: hermes
spec:
selector:
app: gateway
ports:
– name: api
port: 8642
targetPort: 8642
type: ClusterIP
—
kind: PersistentVolumeClaim
apiVersion: v1
metadata:
name: data
namespace: hermes
spec:
accessModes:
– ReadWriteMany
resources:
requests:
storage: 50Gi
storageClassName: nfs-hhus3
—
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: gateway
namespace: hermes
spec:
serviceName: gateway
replicas: 1
selector:
matchLabels:
app: gateway
template:
metadata:
labels:
app: gateway
spec:
nodeSelector:
hosthatch/zone: lax
containers:
– name: gateway
image: nousresearch/hermes-agent:latest
args: [“gateway”, “run”]
ports:
– containerPort: 8642
env:
– name: TZ
value: “Asia/Shanghai”
volumeMounts:
– name: hermes-data
mountPath: /opt/data
resources:
requests:
memory: “1Gi”
cpu: “500m”
limits:
memory: “4Gi”
cpu: “2”
volumes:
– name: hermes-data
persistentVolumeClaim:
claimName: data
“`
## 4. 部署 Dashboard 仪表盘(StatefulSet)
直接给出参考 yaml,按需调整:
“`yaml
apiVersion: v1
kind: Service
metadata:
name: dashboard
namespace: hermes
spec:
selector:
app: dashboard
ports:
– name: web
port: 9119
targetPort: 9119
type: ClusterIP # 按需改为 NodePort / LoadBalancer
—
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: dashboard
namespace: hermes
spec:
serviceName: dashboard
replicas: 1
selector:
matchLabels:
app: dashboard
template:
metadata:
labels:
app: dashboard
spec:
nodeSelector:
hosthatch/zone: lax
containers:
– name: dashboard
image: nousresearch/hermes-agent:latest
args: [“dashboard”]
#args: [“dashboard”, “–host”, “0.0.0.0”, “–insecure”]
ports:
– containerPort: 9119
env:
# 指向 Gateway Service 的 ClusterIP DNS 名称
– name: GATEWAY_HEALTH_URL
value: “http://gateway.hermes.svc.cluster.local:8642”
– name: GATEWAY_HEALTH_TIMEOUT
value: “3”
volumeMounts:
– name: hermes-data
mountPath: /opt/data
readOnly: true # Dashboard 只读数据目录
resources:
requests:
memory: “256Mi”
cpu: “100m”
limits:
memory: “512Mi”
cpu: “500m”
volumes:
– name: hermes-data
persistentVolumeClaim:
claimName: data
“`
可以使用 `port-forward` 安全的访问仪表盘,不建议对外暴露:
“`bash
kubectl port-forward -n hermes svc/hermes-dashboard 9119:9119
# 浏览器访问 http://localhost:9119
“`
## 5. 运行交互式 CLI 聊天
在已部署并配置好的数据目录基础上,可随时进行交互式聊天,使用 `kubectl exec` 进入 Gateway 容器
“`bash
kubectl exec -it -n hermes gateway-0 — /opt/hermes/.venv/bin/hermes
“`
## Refs
– [Hermes Agent 官方 Docker 文档](https://hermes-agent.nousresearch.com/docs/user-guide/docker)
– [nerdctl 文档](https://github.com/containerd/nerdctl)
– [hermes-agent/issues/12398](https://github.com/NousResearch/hermes-agent/issues/12398)
– [nerdctl/issues/128](https://github.com/containerd/nerdctl/issues/128)
2026-04-27 15:00:00
> **适用场景**:K3s 默认不附带 nerdctl,但其内置的 containerd 与 nerdctl 完全兼容。本教程讲解如何在 K3s 节点上以最小代价安装 nerdctl,并正确指向 K3s 的 containerd socket,无需重复安装 containerd 或 CNI。
## 一、背景与原理
| 工具 | 说明 |
|——|——|
| `ctr` | containerd 内置调试工具,与 Docker CLI 不兼容,功能有限 |
| `crictl` | CRI 调试工具,K3s 自带,面向 Kubernetes 运维 |
| `nerdctl` | Docker 兼容 CLI,支持 `run`/`build`/`compose`,**推荐日常使用** |
K3s 的 containerd socket 路径为 `/run/k3s/containerd/containerd.sock`,而非标准路径 `/run/containerd/containerd.sock`。只需在配置中指向该路径,nerdctl 即可接管 K3s 容器管理。
K3s 已自带 CNI 插件(flannel/calico 等),**查看 K3s 节点已有的 Pod 和镜像无需额外 CNI**。若需要 `nerdctl run` 启动独立容器并连接网络,则需要补充安装 CNI 插件(见第四节)。
## 二、安装 nerdctl(仅二进制)
K3s 节点已有 containerd,只需下载 nerdctl 的精简包(**不含** containerd/CNI,体积小)。
### 2.1 下载二进制
“`bash
# 查询最新版本(或手动前往 https://github.com/containerd/nerdctl/releases 查看)
NERDCTL_VERSION=$(curl -s https://api.github.com/repos/containerd/nerdctl/releases/latest \
| grep tag_name | cut -d ‘”‘ -f4 | tr -d ‘v’)
echo “最新版本: ${NERDCTL_VERSION}”
# 下载精简包(仅 nerdctl 二进制)
curl -LO “https://github.com/containerd/nerdctl/releases/download/v${NERDCTL_VERSION}/nerdctl-${NERDCTL_VERSION}-linux-amd64.tar.gz”
“`
> **ARM64 节点**(如树莓派、ARM 服务器)将 `amd64` 替换为 `arm64`:
> “`bash
> curl -LO “https://github.com/containerd/nerdctl/releases/download/v${NERDCTL_VERSION}/nerdctl-${NERDCTL_VERSION}-linux-arm64.tar.gz”
> “`
### 2.2 解压并安装
“`bash
# 解压到 /usr/local/bin
sudo tar Cxzvf /usr/local/bin nerdctl-${NERDCTL_VERSION}-linux-amd64.tar.gz nerdctl
# 验证安装
nerdctl –version
“`
## 三、配置 nerdctl 指向 K3s containerd
nerdctl 默认连接 `/run/containerd/containerd.sock`,在 K3s 节点上需要修改为 K3s 专用路径。
### 3.1 创建配置文件
“`bash
sudo mkdir -p /etc/nerdctl
sudo tee /etc/nerdctl/nerdctl.toml > /dev/null **说明**:
> – `address`:K3s containerd 的 socket 路径
> – `namespace`:K3s 所有容器和镜像均存储在 `k8s.io` 命名空间下
### 3.2 验证连接
“`bash
# 列出 K3s 命名空间下的所有容器(等同于 kubectl get pods 的容器视角)
sudo nerdctl ps -a
# 列出镜像
sudo nerdctl images
“`
如果能看到 K3s 系统 Pod(如 coredns、traefik 等),说明配置成功。
## 四、安装 CNI 插件(按需,用于 nerdctl run)
**如果只需要查看 K3s 已有容器和镜像,可跳过此节。**
只有当你需要用 `nerdctl run` 启动独立容器(即非 Kubernetes 管理的容器)时,才需要 CNI 插件。K3s 自带的 CNI 仅供 Kubernetes 使用,nerdctl 的独立容器网络需要单独配置。
### 4.1 下载官方 CNI 插件
“`bash
CNI_VERSION=$(curl -s https://api.github.com/repos/containernetworking/plugins/releases/latest \
| grep tag_name | cut -d ‘”‘ -f4)
curl -LO “https://github.com/containernetworking/plugins/releases/download/${CNI_VERSION}/cni-plugins-linux-amd64-${CNI_VERSION}.tgz”
# 安装到标准路径
sudo mkdir -p /opt/cni/bin
sudo tar Cxzvf /opt/cni/bin cni-plugins-linux-amd64-${CNI_VERSION}.tgz
“`
### 4.2 创建默认网络配置
“`bash
sudo mkdir -p /etc/cni/net.d
sudo tee /etc/cni/net.d/10-nerdctl-bridge.conflist > /dev/null **注意**:此桥接网络(`10.88.0.0/16`)仅供 nerdctl 管理的独立容器使用,不会影响 K3s 自身网络。
### 4.3 验证独立容器运行
“`bash
# 注意:启动独立容器时需使用默认命名空间(不加 –namespace k8s.io)
# 或在 nerdctl.toml 中临时切换,推荐直接在命令行覆盖:
sudo nerdctl –namespace default run -d –name test-nginx -p 8080:80 nginx:alpine
# 确认运行
sudo nerdctl –namespace default ps
curl http://localhost:8080
“`
## 五、常用命令速查
所有命令均需 `sudo`(或将当前用户加入 containerd 相关权限组)。
### 查看 K3s 容器和镜像
“`bash
# 列出所有容器(K3s 管理)
sudo nerdctl ps -a
# 列出镜像
sudo nerdctl images
# 查看容器日志
sudo nerdctl logs
# 进入容器终端
sudo nerdctl exec -it sh
“`
### 镜像管理
“`bash
# 拉取镜像(拉取后可直接被 K3s Pod 使用)
sudo nerdctl pull nginx:alpine
# 查看镜像详情
sudo nerdctl inspect
# 删除镜像
sudo nerdctl rmi
# 从 tar 包导入镜像(常用于离线环境)
sudo nerdctl load /dev/null