Ubuntu 22.04 安装 Jami 20260403.0 指南

在 Ubuntu 22.04 上从零完成 Jami 服务端形态(jami-daemon)的完整安装与无头(headless)账户注册,覆盖官方 APT 源配置、daemon 运行、D-Bus 方式创建账户并拿到 RingID、systemd 服务常驻与全链路验证,全部命令在 Ubuntu 22.04 实验环境中实测执行。

JamiJami即时通讯VoIPP2P视频会议2026/10/26

Ubuntu 22.04 安装 Jami 20260403.0 指南

目标:在 Ubuntu 22.04 上从零完成 Jami 服务端形态(jami-daemon)的完整安装与无头(headless)账户注册,覆盖官方 APT 源配置、daemon 运行、D-Bus 方式创建账户并拿到 RingID、systemd 服务常驻与全链路验证,全部命令在 Ubuntu 22.04 实验环境中实测执行。

一、环境信息

项值来源
实验系统Ubuntu 22.04(隔离 Linux 实验环境,systemd 已启用,操作与物理机/虚机一致)实测
软件来源官方稳定源 https://dl.jami.net/stable/ubuntu_22.04/(jami main)实测
jami-daemon 版本20260403.0~dfsg1-1(对应稳定版 Jami 20260403.0)apt-cache policy 实测
内核组件版本jamid 自报 Jami Core 16.0.0;OpenDHT 3.7.8jamid --version、daemon 日志实测
dbus-x11 版本1.12.20-2ubuntu4.1(Ubuntu 22.04 基础源)apt-cache policy 实测
实验日期2026-10-26实测
关联文章选型与架构认知见《Jami 20260403.0 介绍与选型指南》;安装后的参数调优与 D-Bus API 细节见本专栏后续配置篇与 API 篇本专栏

💡 说明:本文面向无图形界面的服务器场景,安装的是 jami-daemon(守护进程)而非完整桌面客户端 jami 包;这与官方文档《Jami for servers》的推荐一致(服务器上「install Jami's daemon instead of Jami directly」)。桌面用户的差异仅在第 5 步:把安装目标换成 jami 即可获得 Qt 图形客户端。

二、软件概述

Jami 是 GNU 项目下的分布式 P2P 通信平台,桌面端采用「客户端 + 本地 daemon」形态:图形客户端经 D-Bus 调用本机 jami-daemon(可执行文件 jamid)完成消息、音视频与账户管理;daemon 自身不依赖图形环境,因此可以在无显示器的服务器上独立运行。本次实验的版本链路为:jami-daemon 20260403.0~dfsg1-1(Jami Core 16.0.0)→ OpenDHT 3.7.8 → 公共 DHT 网络 bootstrap.jami.net。原理与同类对比详见 A 篇。

三、实验环境

3.1 实验方案

在 Ubuntu 22.04 宿主上启动一个启用 systemd 的隔离实验环境(桥接网络 10.89.58.0/24,主机名 jamisrv1),在其中完整执行从空系统到「daemon 运行 + 账户注册成功」的全过程。命令、回显与版本号均为实测照抄。

3.2 版本记录

$ apt-cache policy jami-daemon dbus-x11
jami-daemon:
  Installed: 20260403.0~dfsg1-1
  Candidate: 20260403.0~dfsg1-1
  Version table:
 *** 20260403.0~dfsg1-1 500
        500 https://dl.jami.net/stable/ubuntu_22.04 jami/main amd64 Packages
        100 /var/lib/dpkg/status
dbus-x11:
  Installed: 1.12.20-2ubuntu4.1
  Candidate: 1.12.20-2ubuntu4.1
$ /usr/libexec/jamid --version
Jami Core 16.0.0, by Savoir-faire Linux Inc. Copyright (C) 2004-2025
https://jami.net/

四、前置条件

  1. 一台 Ubuntu 22.04 主机(物理机/虚机/云主机均可),具备 sudo 权限。
  2. 出网能力:需要访问 dl.jami.net(安装包)与 DHT 公共基础设施——bootstrap.jami.net:4222(引导节点)、turn.jami.net(TURN 中继,UDP/TCP 3478、5349)。
  3. 无图形环境需补装 dbus-x11(提供 dbus-launch);本篇实验中该包版本为 1.12.20-2ubuntu4.1。
  4. 磁盘空间:jami-daemon 包本体约 20 MB 级别,加上依赖与账户数据预留 500 MB 足够。

五、安装步骤

5.1 配置官方 APT 源

安装前置工具并写入官方 GPG 公钥与源文件(命令与官方文档《Set up Jami → Ubuntu》一致):

sudo apt install gnupg dirmngr ca-certificates curl --no-install-recommends
curl -s https://dl.jami.net/public-key.gpg | sudo tee /usr/share/keyrings/jami-archive-keyring.gpg > /dev/null
sudo sh -c "echo 'deb [signed-by=/usr/share/keyrings/jami-archive-keyring.gpg] https://dl.jami.net/stable/ubuntu_22.04/ jami main' > /etc/apt/sources.list.d/jami.list"
sudo apt-get update

实测要点:apt-get update 后源索引生效,随后 apt-cache policy 即可看到上文 3.2 的版本表(500 优先级来自 dl.jami.net)。

5.2 安装 daemon 与 D-Bus 工具

sudo apt-get install -y jami-daemon dbus-x11

安装完成后核对关键文件落位:

$ dpkg -L jami-daemon | grep -E "bin/|libexec"
/usr/libexec
/usr/libexec/jamid

⚠️ 注意:老教程里的 dring 命令在 20260403.0 包中已不存在,守护进程唯一二进制是 /usr/libexec/jamid(dpkg -L jami-daemon 共 40 个文件)。若按历史文档执行 dring 会得到 command not found,属正常现象,直接使用 jamid 即可。

若需要图形客户端(桌面机):

sudo apt-get install -y jami

六、无头环境注册账户(命令行 + D-Bus)

服务器上没有图形向导,官方路径是:专用用户 → 私有会话 D-Bus → 启动 jamid → 经 D-Bus ConfigurationManager.addAccount 创建账户。

6.1 创建运行账户

sudo useradd -s /bin/bash -m jamiserver

6.2 启动私有 D-Bus 与 daemon

切换到 jamiserver,启动一条私有会话总线,把总线地址记入文件,再以前台 debug 模式拉起 daemon:

sudo -iu jamiserver
eval $(dbus-launch --sh-syntax)
echo "$DBUS_SESSION_BUS_ADDRESS" > /tmp/dbusaddr
nohup /usr/libexec/jamid -c -d > /tmp/jamid.log 2>&1 &

jamid 参数说明:-c(console,日志输出到控制台)、-d(debug 级别)。观察日志确认 OpenDHT 栈版本与账户加载:

$ grep -a "OpenDHT version" /tmp/jamid.log
[1792993572.201|3958|manager.cpp :781 ] Using OpenDHT version: 3.7.8

6.3 经 D-Bus 创建 Jami 账户

addAccount 接收一组键值对;创建标准 Jami 账户只需声明类型(RING 即 Jami 账户)与别名。以下为实测命令(accountID 由 daemon 生成返回):

busctl --user call cx.ring.Ring /cx/ring/Ring/ConfigurationManager \
  cx.ring.Ring.ConfigurationManager addAccount "a{ss}" 4 \
  "Account.type" "RING" \
  "Account.alias" "headless-srv1" \
  "Account.displayName" "headless-srv1" \
  "Account.archivePath" ""

返回(照抄实测):

s "ff5bdfae563e6707"

s 后的 ff5bdfae563e6707 即 accountID,后续所有 D-Bus 调用都以它定位账户。

6.4 确认账户清单与 RingID

busctl --user call cx.ring.Ring /cx/ring/Ring/ConfigurationManager \
  cx.ring.Ring.ConfigurationManager getAccountList ""
as 1 "ff5bdfae563e6707"

RingID 来自 getAccountDetails 中的 Account.username 键(40 位十六进制公钥指纹):

Account.alias = headless-srv1
Account.hostname = bootstrap.jami.net
Account.type = RING
Account.username = 813cbf71078e4d16b0462ce1c694c54bc2f52979

即本实验服务器的 RingID 为 813cbf71078e4d16b0462ce1c694c54bc2f52979。

6.5 确认 DHT 注册状态

账户是否真正进入网络,看 getVolatileAccountDetails 的三个键(volatile 详情实时反映运行态):

"Account.active" "true"
"Account.deviceAnnounced" "true"
"Account.dhtBoundPort" "33089"
"Account.registrationStatus" "REGISTERED"

registrationStatus = REGISTERED 表示该 RingID 已在公共 DHT 网络可寻址,deviceAnnounced = true 表示设备证书已在网络宣告。对应的 daemon 日志:

[Account ff5bdfae563e6707] Bootstrap node: bootstrap.jami.net
[Account ff5bdfae563e6707] DHT status: IPv4 connecting; IPv6 disconnected
[Account ff5bdfae563e6707] DHT status: IPv4 connected; IPv6 disconnected
[Account ff5bdfae563e6707] Connected

6.6 账户数据落位

~/.config/jami/
└── dring.yml                          # daemon 全局配置

~/.local/share/jami/
├── local_device_id
└── ff5bdfae563e6707/                  # 以 accountID 命名的账户目录
    ├── archive.gz                     # 账户 archive(可导出 .jac 备份的本地形态)
    ├── config.yml                     # 账户级配置
    ├── contacts  convInfo  convRequests  knownDevices
    ├── certificates/  crls/  oscp/
    ├── ring_device.crt                # 设备证书
    └── ring_device.key                # 设备私钥(600 权限)

⚠️ 注意:账户私钥只存在于设备本地。~/.local/share/jami/<accountID>/archive.gz 丢失且无其他设备链接时账户不可恢复,安装完成即应规划备份(导出 .jac 的操作见 API 篇)。

七、systemd 服务常驻

实测通过后,按官方文档《Jami for servers》把 daemon 注册为系统服务。

第 1 步:以 root 创建 /usr/local/bin/launchjami(内容为官方原文,负责拉起私有会话总线并把地址写到 /tmp/env-jamiserver):

#!/bin/bash
dbus-launch --auto-syntax|grep DBUS_SESSION_BUS_ADDRESS >/tmp/env-jamiserver
source /tmp/env-jamiserver
/usr/libexec/jamid
sudo chmod +x /usr/local/bin/launchjami

第 2 步:创建 /etc/systemd/system/jamiserver.service(官方原文):

[Unit]
Description=Daemon Jami for my project
After=network-online.target

[Service]
Type=simple
ExecStart=/usr/local/bin/launchjami
ExecStop=/usr/bin/pkill -u jamiserver jamid
User=jamiserver
Group=jamiserver

[Install]
WantedBy=default.target

第 3 步:启用并启动:

sudo systemctl daemon-reload
sudo systemctl enable jamiserver.service
sudo systemctl start jamiserver.service

enable 实测输出:Created symlink /etc/systemd/system/default.target.wants/jamiserver.service → /etc/systemd/system/jamiserver.service.

第 4 步:状态确认(systemctl status jamiserver.service --no-pager -l 实测节选):

● jamiserver.service - Daemon Jami for my project
     Loaded: loaded (/etc/systemd/system/jamiserver.service; enabled; vendor preset: enabled)
     Active: active (running) since Mon 2026-10-26 05:48:28 UTC; 4s ago
   Main PID: 4112 (launchjami)
      Tasks: 23 (limit: 2932)
     Memory: 8.9M
     CGroup: …/system.slice/jamiserver.service
             ├─4112 /bin/bash /usr/local/bin/launchjami
             ├─4119 /usr/bin/dbus-daemon --syslog --fork --print-pid 4 --print-address 6 --session
             └─4120 /usr/libexec/jamid

Oct 26 05:48:28 jamisrv1 jami[4120]: [Account ff5bdfae563e6707] DHT status: IPv4 connected; IPv6 connecting

服务化后验证账户仍在线(注意必须以 jamiserver 身份连接其会话总线,见第九节第 2 条):

sudo -iu jamiserver bash -c 'source /tmp/env-jamiserver; \
  busctl --user call cx.ring.Ring /cx/ring/Ring/ConfigurationManager \
  cx.ring.Ring.ConfigurationManager getVolatileAccountDetails "s" ff5bdfae563e6707'

实测输出含 "Account.registrationStatus" "REGISTERED",服务重启后账户自动重连成功。

八、安装验证

全链路验证点汇总(全部实测通过):

#验证点命令/方法通过标准实测结果
1源与版本apt-cache policy jami-daemonCandidate 来自 dl.jami.net20260403.0~dfsg1-1 ✅
2daemon 存在/usr/libexec/jamid --version输出版本Jami Core 16.0.0 ✅
3daemon 运行ps aux | grep jamid进程存活PID 4120 ✅
4D-Bus 注册busctl --user list | grep cx.ring出现 cx.ring.Ring✅
5账户存在getAccountList返回 accountIDff5bdfae563e6707 ✅
6RingID 生成getAccountDetails 的 Account.username40 位十六进制813cbf71…52979 ✅
7网络注册volatile 详情registrationStatus=REGISTERED✅
8数据落盘检查 6.6 目录dring.yml/账户目录齐备✅
9服务常驻systemctl status jamiserveractive (running)、enabled✅

九、常见问题(实测命中)

  1. dring 不存在:20260403.0 的 jami-daemon 包只提供 /usr/libexec/jamid,老文档中的 dring 命令一律替换为 jamid;配置文件名仍保留历史命名 ~/.config/jami/dring.yml(文件名带 dring、可执行文件叫 jamid,二者并存是当前版本的真实形态)。
  2. root 执行 busctl 报 Transport endpoint is not connected:会话 D-Bus 属于创建它的用户(jamiserver),默认策略拒绝其他 UID 接入。实测 root 连接必现此错,切到 sudo -iu jamiserver 后正常。这是排障时最容易踩的坑:命令没写错,只是「谁的总线」用错了。
  3. 日志出现 DHT UPnP mapping … state=FAILED:在无 UPnP 网关的实验环境(云主机默认网络常见)必现,daemon 会自动回落直连公共 DHT,不影响 registrationStatus=REGISTERED;家用路由/开启 UPnP 的环境会显示 MAPPED。
  4. DHT status: IPv4 connected; IPv6 disconnected:实验环境未分配 IPv6,公共 DHT 的 IPv6 节点不可达属预期;只影响部分节点发现效率,不影响注册。
  5. 账户注册后 Account.registeredName 为空:未注册用户名(默认 ns.jami.net 的区块链用户名)时该键为空串,不影响 P2P 互通——对方直接用 40 位 RingID 添加联系人即可。
  6. desktop 与 daemon 装在同一台机的冲突:jami(Qt 客户端)与 jami-daemon 的 D-Bus 名相同,同用户同总线只会跑一个实例;服务器场景装 jami-daemon 即可,不要混装客户端。

十、双端互通验证路径

单服务器环境无法独立完成双端通话/收发消息的闭环(至少需要第二个 Jami 端点),按下列路径任选其一完成互通验证:

  1. 图形端点(最快):在任一台桌面机/手机安装 Jami 客户端,创建第二个账户后,以服务器 RingID 813cbf71078e4d16b0462ce1c694c54bc2f52979 添加联系人并发起会话;服务器侧无图形界面,可通过 D-Bus 监听 messagesReceived/incomingCall 信号观察到达情况(监听命令见 API 篇)。
  2. 服务器主动外呼:以服务器为发起方,经 D-Bus placeCall(或 sendTextMessage)向对端 RingID 拨打,观察 callStateChanged/messagesReceived 回调路径,同样需要真实对端在线才能闭环。
  3. 验证要点:双方 registrationStatus 均为 REGISTERED 且能互加联系人是互通的充分前提;内网互通可完全脱离公网(自建 bootstrap,见 C 篇 DHT 引导节点配置)。

十一、卸载

sudo systemctl disable --now jamiserver.service
sudo rm -f /etc/systemd/system/jamiserver.service /usr/local/bin/launchjami /tmp/env-jamiserver
sudo systemctl daemon-reload
sudo apt-get purge -y jami-daemon dbus-x11   # dbus-x11 为系统基础组件,视需要保留
sudo rm -rf /etc/apt/sources.list.d/jami.list /usr/share/keyrings/jami-archive-keyring.gpg
sudo rm -rf /home/jamiserver/.config/jami /home/jamiserver/.local/share/jami   # 账户数据,含私钥,确认无需备份后删除
sudo userdel -r jamiserver

十二、参考链接