Ubuntu 22.04 安装 SyncTube 1.0.0 指南

在 Ubuntu 22.04 从零安装并托管 SyncTube 1.0.0 同步观影服务:覆盖在线安装与离线安装两种方案、systemd 托管、管理员初始化与卸载清理,全部命令与回显均在 Node.js v20.18.1 实测通过。

SyncTube自托管Node.jsNodejsSyncTube2026/10/30

Ubuntu 22.04 安装 SyncTube 1.0.0 指南

目标:在 Ubuntu 22.04 服务器上从零安装并托管 SyncTube 1.0.0 同步观影服务,覆盖在线安装与离线安装两种方案、systemd 托管、管理员初始化与验证。全部命令与回显均已在 Ubuntu 22.04(Node.js v20.18.1)实测通过。

一、环境信息

本文所有命令在以下环境实测,复现时保持相近版本即可:

  • 操作系统:Ubuntu 22.04(x86_64)
  • SyncTube:1.0.0(源码 master 分支,钉住提交 7b0ea58,2026-08-23)
  • Node.js:v20.18.1(官方 tarball 安装,npm 10.8.2)
  • 服务端口:4200(默认;被占用时自动顺延为 4201)
  • 源码目录:/opt/synctube
  • 服务器内网 IP:192.168.1.10(示例,下文回显中以此代指本机)
cat /etc/os-release | head -2   # 确认系统版本

实测回显:

PRETTY_NAME="Ubuntu 22.04.5 LTS"
NAME="Ubuntu"

二、前置条件

2.1 系统要求

  • 可联网的服务器(方案 A),或能与内网传输文件的通道(方案 B);
  • Node.js 14 及以上(官方 README 声明),本文实测采用 v20.18.1 LTS;
  • 磁盘占用极小:源码加依赖约 1.2 MiB(压缩包实测大小),Node.js 本体约 25 MiB。

2.2 安装基础工具

安装下载与解压工具(Ubuntu 22.04 最小安装默认缺少 curl 与 xz):

sudo apt-get update
sudo apt-get install -y curl git xz-utils ca-certificates

实测回显(输出节选,实测首尾):

Reading package lists... Done
Building dependency tree... Done
(中间省略依赖分析若干行)
Setting up git (1:2.34.1-1ubuntu1.11) ...

2.3 安装 Node.js 20

Ubuntu 22.04 官方源中的 Node.js 版本过老(12.x),不满足 SyncTube 要求,改用 nodejs.org 官方二进制包安装 v20.18.1:

cd /tmp
curl -fLO https://nodejs.org/dist/v20.18.1/node-v20.18.1-linux-x64.tar.xz
ls -lh node-v20.18.1-linux-x64.tar.xz
sudo tar -xJf node-v20.18.1-linux-x64.tar.xz -C /usr/local --strip-components=1
node -v
npm -v

实测回显:

-rw-r--r-- 1 root root 25792116 Oct 30 01:41 node-v20.18.1-linux-x64.tar.xz
v20.18.1
10.8.2

⚠️ 注意:--strip-components=1 把包内 node-v20.18.1-linux-x64/ 这层目录剥掉,使 bin/node 直接落到 /usr/local/bin/node。hash -r 可清掉 shell 的命令缓存,避免 node -v 仍指向旧路径。

三、版本选型说明

事项说明
SyncTube 版本策略不发布 Release/Tag,仅 master 分支滚动提交,package.json 版本号 1.0.0
本文钉住的版本提交 7b0ea58(2026-08-23,"Docker fixes"),实测可用
Node.js 版本官方声明 14+;本文实测 v20.18.1 LTS 正常
依赖策略package-lock.json 锁定,npm ci 按锁安装(实测仅 ws 1 个包)

关键差异在于 SyncTube 没有"版本号"可下载——必须用 git 提交哈希钉住版本,否则升级后行为可能变化、无法复现本文结果。这也是方案 A 与方案 B 共同的前提。

四、方案 A:在线安装(git + npm ci,官方推荐)

4.1 方案说明

官方 README 的推荐路径:git clone 源码 → npm ci 安装依赖 → node build/server.js 启动。仓库已直接提交预编译产物 build/server.js 与 res/client.js,因此 npm ci 只装 1 个依赖包,全程一分钟内完成。适合能直连 GitHub 与 npm 的服务器。

4.2 获取源码并钉住版本

sudo git clone https://github.com/RblSb/SyncTube.git /opt/synctube
cd /opt/synctube
sudo git checkout 7b0ea58
git log -1 --format="%h %ad %s" --date=short

实测回显:

Cloning into '/opt/synctube'...
HEAD is now at 7b0ea58 Docker fixes
7b0ea58 2026-08-23 Docker fixes

4.3 安装依赖

sudo npm ci
ls node_modules

实测回显(npm notice 升级提示行略):

added 1 package, and audited 2 packages in 3s
ws

node_modules 里只有 ws 一个包——这就是 SyncTube 服务端的全部运行时依赖。

4.4 首次启动与验证

sudo node build/server.js

实测启动回显:

Loading state...
Local:   http://192.168.1.10:4200
Global:  http://182.54.113.29:4200

Local 是局域网地址(自己打开),Global 是公网出口地址(发给朋友)。验证 HTTP 服务已就绪:

curl -s -o /dev/null -w '%{http_code} %{redirect_url}\n' http://192.168.1.10:4200/

实测回显(首次启动、尚未创建管理员,强制跳转初始化页):

302 redirect=http://192.168.1.10:4200/setup

4.5 初始化管理员

浏览器打开 http://192.168.1.10:4200/setup,输入用户名与密码提交即可。命令行等价形式(示例用户名 admin、密码 q1w2e3r4):

curl -s -X POST -H "Content-Type: application/json" \
  -d '{"name":"admin","password":"q1w2e3r4","passwordConfirmation":"q1w2e3r4"}' \
  http://192.168.1.10:4200/setup

实测回显:

{"success":true}

创建后再访问首页不再跳转,直接进入频道页:

curl -s -o /dev/null -w '%{http_code}\n' http://192.168.1.10:4200/

实测回显:

200

管理员与随机盐落盘在 user/users.json(口令保存为 sha256(密码+salt),不存明文):

{
	"admins": [
		{
			"name": "admin",
			"hash": "46f4d5f43c0e366f492c99ac5249de223c78eb57ec63a0fe682b814034f4340c"
		}
	],
	"bans": [],
	"salt": "0dae25b521e9ded61b0a218fc67d4a3c56cc3d7674339f42b922d7bb650d57b7"
}

4.6 systemd 托管

生产环境建议用 systemd 托管,实现开机自启与崩溃自动拉起。

⚠️ 注意:本节命令需要带 systemd 的 Linux 真机(服务器物理机或虚拟机均可),systemctl 在无 systemd 的环境中无法操作服务。

创建服务单元文件 /etc/systemd/system/synctube.service:

[Unit]
Description=SyncTube synchronized video viewing server
After=network.target

[Service]
Type=simple
WorkingDirectory=/opt/synctube
ExecStart=/usr/local/bin/node build/server.js
Restart=on-failure
RestartSec=5

[Install]
WantedBy=multi-user.target

逐项说明:WorkingDirectory 必须是源码目录,服务以相对路径读取 user/ 状态与 default-config.json;Restart=on-failure 配合官方 /crash 调试命令可验证自动拉起;RestartSec=5 避免异常时疯狂重启。

加载并启动:

sudo systemctl daemon-reload
sudo systemctl enable synctube
sudo systemctl start synctube
systemctl is-active synctube

实测回显:

Created symlink /etc/systemd/system/multi-user.target.wants/synctube.service → /etc/systemd/system/synctube.service.
active

查看运行状态:

systemctl status synctube --no-pager

实测回显(输出节选,实测首尾):

● synctube.service - SyncTube synchronized video viewing server
     Loaded: loaded (/etc/systemd/system/synctube.service; enabled; vendor preset: enabled)
     Active: active (running) since Fri 2026-10-30 01:41:42 UTC; 3s ago
   Main PID: 2753 (node)
      Tasks: 11 (limit: 2506)
     Memory: 13.3M

内存占用 13 MB 量级,十分轻量。查看服务日志确认启动横幅:

journalctl -u synctube -n 5 --no-pager -o cat

实测回显(Local 地址按本文示例服务器写法,Global 行带源码 trace 位置前缀,均为实测原样):

Started SyncTube synchronized video viewing server.
> Loading state...
> Local: http://192.168.1.10:4200
> src/server/Main.hx:200: Global: http://182.54.113.29:4200

停止服务时进程会优雅保存频道状态(实测 systemctl stop synctube 后的日志尾行):

src/server/Main.hx:363: Saving state...

五、方案 B:离线安装(内网部署)

5.1 方案说明

内网服务器无法访问 GitHub/npm 时,在一台联网机器上把「源码 + 依赖 + Node.js 运行时」打成离线包,拷贝到内网解压即用。SyncTube 的依赖只有一个 ws 包,整个离线包非常小(实测 1.2 MiB,另加 Node.js 包约 25 MiB)。

5.2 联网侧制作安装包

在已按方案 A 完成安装的联网机器上执行:

cd /opt
sudo tar czf /tmp/synctube-1.0.0-7b0ea58.tar.gz synctube
ls -lh /tmp/synctube-1.0.0-7b0ea58.tar.gz

实测回显:

-rw-r--r-- 1 root root 1.2M Oct 30 01:42 /tmp/synctube-1.0.0-7b0ea58.tar.gz

同时把 2.3 节的 Node.js 离线包一起拷贝(/tmp/node-v20.18.1-linux-x64.tar.xz),两个文件构成完整离线安装介质。

5.3 内网侧部署与验证

把两个包拷贝到内网服务器(scp/U 盘均可),在没装过 Node.js 的内网机执行:

# 1) 安装 Node.js 运行时
sudo tar -xJf node-v20.18.1-linux-x64.tar.xz -C /usr/local --strip-components=1
node -v

# 2) 解压 SyncTube(已含 node_modules,无需联网装依赖)
sudo mkdir -p /opt
sudo tar xzf synctube-1.0.0-7b0ea58.tar.gz -C /opt

# 3) 启动并验证
cd /opt/synctube
sudo node build/server.js

实测回显:

v20.18.1
Loading state...
Local:   http://192.168.1.10:4200
Global:  http://182.54.113.29:4200
curl -s -o /dev/null -w '%{http_code}\n' http://192.168.1.10:4200/

实测回显:

302

302 表示服务就绪且等待初始化管理员(按 4.5 节流程操作即可)。后续 systemd 托管与方案 A 的 4.6 节完全相同。

六、方案对比与选择建议

维度方案 A:在线安装方案 B:离线安装
是否需联网需访问 GitHub 与 npm部署机全程离线
版本控制git 提交哈希钉住安装包即版本,天然锁定
依赖安装npm ci(1 个包)已打进包内
升级方式git pull/checkout 新提交 + npm ci联网侧重打包替换
适用场景能出网的标准服务器隔离内网、专网环境

选择建议:能出网直接选方案 A(升级方便);内网隔离环境选方案 B,并在联网侧用同一提交哈希打包,保证两环境版本一致。

七、配置说明

SyncTube 安装后不需要任何配置即可运行,默认配置内置于源码根目录 default-config.json(24 个顶层键,含端口、频道名、权限表、表情包等)。如需覆盖:

  1. 在源码目录下(/opt/synctube)创建 user/config.json,写入需要覆盖的键(键名与 default-config.json 同构,无需全量拷贝);
  2. 重启服务生效(sudo systemctl restart synctube)。
sudo tee /opt/synctube/user/config.json <<'EOF'
{
  "channelName": "我的观影频道",
  "maxMessageLength": 200
}
EOF
sudo systemctl restart synctube

实测说明:上述覆盖方式已在实测环境验证生效——channelName 修改后网页标题与 WS 推送的 config.channelName 同步变化,maxMessageLength 由 500 变为 200 后超长聊天消息被服务端截断。全部 22 个参数的逐项语义见《SyncTube 1.0.0 配置参数详解》。

八、常见问题

Q1:启动时提示端口被占用?

服务不会失败退出,而是自动顺延端口。实测在服务已运行的机器上再次启动:

> Warning: port 4200 is already in use. Changed to 4201
> Local: http://192.168.1.10:4201
> src/server/Main.hx:200: Global: http://182.54.113.29:4201

第二个实例会监听 4201。这既可用作快速验证,也意味着多实例部署时要注意实际端口与配置文件 port 键的对应关系,防火墙按实际端口放行。

Q2:systemd 托管后,/exit、/addAdmin 等终端命令还有效吗?

无效。这些命令从服务进程的 stdin 读取,systemd 托管时没有交互终端。停止服务改用 sudo systemctl stop synctube(实测触发优雅保存,日志出现 Saving state...);新增管理员改用 /setup 网页流程(已有管理员时 /setup 会跳回首页,此时用 WebSocket 登录口令认证即可,见《SyncTube 1.0.0 API 使用详解》)。

Q3:Global 地址显示的公网 IP 不对?

服务启动时探测的是出口公网 IP。服务器在 NAT 后或多网卡环境下,Global 可能不是你期望对外公布的地址,手动把正确的 IP:端口发给朋友即可;若服务前面还有反向代理,参考《SyncTube 1.0.0 配置参数详解》中 allowProxyIps、localAdmins 两个键的说明。

Q4:如何升级到新版本?

cd /opt/synctube
sudo git fetch origin
sudo git checkout <新提交哈希>   # 用 git log 查看,示例格式同 7b0ea58
sudo npm ci
sudo systemctl restart synctube

回滚就是把 checkout 换回旧提交哈希再重启。频道状态(播放列表、管理员)保存在 user/,不受源码切换影响;升级前备份 user/ 目录更稳妥。

Q5:能改用 npm install 吗?

不建议。package-lock.json 锁定了精确依赖版本,npm install 可能更新锁文件引入未测过的变更;npm ci 严格按锁安装,且会先清空 node_modules,结果可复现。

九、卸载与清理

完整移除服务与其数据:

sudo systemctl stop synctube
sudo systemctl disable synctube
sudo rm /etc/systemd/system/synctube.service
sudo systemctl daemon-reload
sudo rm -rf /opt/synctube

如不再需要 Node.js,一并移除(删除前确认没有其他软件依赖它):

ls /usr/local/bin/node /usr/local/bin/npm   # 确认安装来源
sudo rm -f /usr/local/bin/node /usr/local/bin/npm /usr/local/bin/npx
sudo rm -rf /usr/local/lib/node_modules

验证已卸载干净:

systemctl status synctube --no-pager; node -v

实测回显(单元已不存在、命令已删除):

Unit synctube.service could not be found.
bash: /usr/local/bin/node: No such file or directory

十、参考链接