Ubuntu 22.04 安装 remark42 指南
Ubuntu 22.04 从零安装 remark42 v1.18.0:官方二进制在线与离线两条完整实测方案、systemd 托管、页面嵌入与评论闭环验证、版本切换实测、remark42.js 404 与 noexec 等排障实录、卸载清理,全部命令与回显逐条实测于 2026-10-22。
Ubuntu 22.04 安装 remark42 指南
目标:在 Ubuntu 22.04 服务器上从零安装 remark42 v1.18.0 评论引擎并完成 systemd 托管、页面嵌入与评论闭环验证,覆盖「官方二进制在线安装」与「离线包部署」两条完整方案、方案对比、升级与多版本管理、常见故障实录与卸载清理。全部命令与回显已在 Ubuntu 22.04.5 LTS 环境逐条实测通过(实测版本 remark42 v1.18.0,HTTP 监听端口 8131)。
一、环境信息
本章列出实测环境与关键可复现信息,正文所有命令与回显均来自该环境。
- 操作系统:Ubuntu 22.04.5 LTS(
/etc/os-release实测PRETTY_NAME="Ubuntu 22.04.5 LTS"),x86_64/amd64 架构; - remark42 版本:v1.18.0(上游最新稳定版,二进制自报版本
remark42 v1.18.0-13b2035c-20261011T191723); - 实测时间:2026-10-22;
- 服务器内网 IP:
10.89.57.2(演示环境直连场景;生产环境建议为 remark42 配置对外域名并把REMARK_URL写成https://评论域名); - 端口规划:remark42 HTTP 服务监听 8131(默认 8080,本文改绑 8131;绑定前已用
ss -ltn确认空闲),静态测试页服务监听 8136(验证页面嵌入用); - 安装目录规划:
- 二进制:
/opt/remark42/bin/remark42.linux-amd64; - 运行数据(bolt 数据库、头像、图片):
/opt/remark42/var/; - 备份目录:
/opt/remark42/backup/; - 环境变量文件:
/opt/remark42/remark42.env; - systemd 服务单元:
/etc/systemd/system/remark42.service;
- 二进制:
- 运行账户:专用系统用户
remark42(实测uid=999(remark42) gid=999(remark42),无登录 shell); - 演示站点 ID:
mysite; - 演示管理员凭据:管理接口 Basic Auth 账号
admin、密码q1w2e3r4(对应环境变量ADMIN_PASSWD=q1w2e3r4)。
二、前置条件
本章说明安装前需要准备好的系统与网络条件。
- 操作系统与权限:Ubuntu 22.04(20.04/24.04 同样适用),具备 root 或 sudo 权限;
- 基础工具:
wget/curl、tar、ca-certificates、openssl(生成密钥用)、iproute2(ss命令查端口占用),Ubuntu 22.04 最小安装通常已自带,缺失时补齐:
apt-get update && apt-get install -y curl wget tar ca-certificates openssl iproute2
- 网络:在线方案需要能访问 GitHub Releases(下载约 10.8MB 安装包);访问慢时可走 HTTP 代理(
curl -x http://<代理地址>:<端口>);离线方案不需要目标机联网(见第五章); - 端口:确认计划使用的端口未被占用(本文用 8131):
ss -ltn | grep 8131
实测回显(空闲时无任何输出,若已有监听会列出对应行;下例为安装完成后 remark42 已监听的对照状态):
LISTEN 0 4096 *:8131 *:* users:(("remark42.linux-",pid=3393,fd=6))
⚠️ 注意:remark42 服务端是自包含的 Go 二进制,不依赖任何外部数据库与运行时;Ubuntu 22.04 原生环境无需额外安装任何语言运行时或数据库。
三、版本选型说明
本章给出版本认定依据与各平台安装包对照,避免装到过时或错误架构的包。
- 最新稳定版认定:v1.18.0,双源交叉验证——GitHub Releases Atom 流(
https://github.com/umputun/remark42/releases.atom)最新 entryVersion 1.18.0(updated2026-10-11T19:31:02Z);releases/latest重定向亦指向v1.18.0(查询日期 2026-10-22); - 二进制自报版本格式(v1.18.0 实测):
remark42 v1.18.0-13b2035c-20261011T191723,由「版本号-提交哈希-构建时间」组成; - 官方发布资产清单(v1.18.0,来源:GitHub Releases 页 expanded_assets,查询日期 2026-10-22):
| 安装包 | 适用平台 |
|---|---|
remark42.linux-amd64.tar.gz | Linux x86_64(本文使用) |
remark42.linux-arm64.tar.gz | Linux ARM64 |
remark42.linux-386.tar.gz | Linux 32 位 x86 |
remark42.darwin-amd64.tar.gz / darwin-arm64.tar.gz | macOS Intel / Apple Silicon |
remark42.freebsd-amd64.tar.gz | FreeBSD x86_64 |
remark42.windows-amd64.zip | Windows x86_64 |
remark42_1.18.0_checksums.txt | 全部资产 SHA256 校验清单 |
关键差异与选型说明:安装包与操作系统/架构一一对应,选择错误架构会直接 cannot execute binary file;官方提供 remark42_1.18.0_checksums.txt 统一校验清单,生产部署应务必核对 SHA256(第四章实测演示)。
四、在线安装方案(A:官方二进制 + systemd 托管)
本章是主推方案:从官方 Releases 下载二进制,创建专用用户与目录,写环境变量文件,用 systemd 托管为常驻服务,最后完成页面嵌入与评论闭环验证。
4.1 下载安装包并校验
先创建工作目录并下载安装包(约 10.8MB):
mkdir -p /opt/remark42 && cd /opt/remark42
wget https://github.com/umputun/remark42/releases/download/v1.18.0/remark42.linux-amd64.tar.gz
实测回显(节选):
--2026-10-22 01:57:12-- https://github.com/umputun/remark42/releases/download/v1.18.0/remark42.linux-amd64.tar.gz
HTTP request sent, awaiting response... 200 OK
Length: 10877078 (10M) [application/octet-stream]
Saving to: 'remark42.linux-amd64.tar.gz'
remark42.linux-amd64.tar.gz 100%[=====================================>] 10.37M 5.85MB/s in 1.8s
核对官方 SHA256(从官方 checksums 清单取期望值,与本地实算比对):
sha256sum remark42.linux-amd64.tar.gz
curl -sL https://github.com/umputun/remark42/releases/download/v1.18.0/remark42_1.18.0_checksums.txt | grep linux-amd64
实测回显(两行哈希完全一致,校验通过):
0f7fa39f30e30123bbbeaf2956fc335ea13d7b5d6799cee20060a303be730d9a remark42.linux-amd64.tar.gz
0f7fa39f30e30123bbbeaf2956fc335ea13d7b5d6799cee20060a303be730d9a remark42.linux-amd64.tar.gz
查看包内容并确认版本(remark42 二进制执行任何命令都会先打印一行版本号,可用 --help 取版本行):
tar tzf remark42.linux-amd64.tar.gz
tar xzf remark42.linux-amd64.tar.gz -C /opt/remark42/bin --strip-components=0
⚠️ 注意:tar 包根目录直接就是三个文件(无顶层目录),不要带
--strip-components=1。正确做法是先建好 bin 目录再解压:
mkdir -p /opt/remark42/bin && tar xzf remark42.linux-amd64.tar.gz -C /opt/remark42/bin && chmod +x /opt/remark42/bin/remark42.linux-amd64
包内容实测回显:
LICENSE
README.md
remark42.linux-amd64
版本确认实测回显:
/opt/remark42/bin/remark42.linux-amd64 --help 2>&1 | head -1
remark42 v1.18.0-13b2035c-20261011T191723
4.2 创建专用用户与目录结构
以非 root 专用系统用户运行服务是安全基线。创建无登录 shell 的系统用户并规划目录:
useradd -r -s /usr/sbin/nologin remark42
id remark42
mkdir -p /opt/remark42/bin /opt/remark42/var /opt/remark42/backup
chown -R remark42:remark42 /opt/remark42
实测回显:
uid=999(remark42) gid=999(remark42) groups=999(remark42)
4.3 编写环境变量文件
remark42 的全部配置通过环境变量注入(REMARK42_ 前缀为旧文档写法,当前版本环境变量直接使用裸名如 REMARK_URL/SECRET/SITE,与二进制 --help 中 [$ENV_VAR] 标注一致)。先生成随机 JWT 密钥,再写环境变量文件:
openssl rand -hex 24
实测回显(每台机器生成的值都不同,用你自己的输出替换):
530108254a0b822ff52e24557efde094ec2ff140d25b80d3
写入 /opt/remark42/remark42.env(实测文件全文):
REMARK_URL=http://10.89.57.2:8131
SECRET=530108254a0b822ff52e24557efde094ec2ff140d25b80d3
SITE=mysite
STORE_TYPE=bolt
STORE_BOLT_PATH=/opt/remark42/var
BACKUP_PATH=/opt/remark42/backup
REMARK_PORT=8131
AUTH_ANON=true
ADMIN_SHARED_ID=auth_anon_admin01
ADMIN_SHARED_EMAIL=admin@example.org
ADMIN_PASSWD=q1w2e3r4
TIMEZONE=Asia/Shanghai
逐项说明:
REMARK_URL:服务的对外访问地址,嵌入页面的浏览器要能直达该地址;生产环境写https://评论服务域名;SECRET:JWT 签名密钥,泄露即等于评论身份体系被伪造,必须用随机长串并妥善保护文件权限;SITE:站点 ID,页面嵌入代码里的site_id必须与此一致(多站点可用逗号分隔配置多个);STORE_TYPE=bolt:使用内嵌 bolt 单文件存储(默认值,显式写出便于日后切换);STORE_BOLT_PATH:bolt 数据文件所在目录,数据库文件按站点 ID 命名(站点mysite生成mysite.db);BACKUP_PATH:自动/手动备份的输出目录;REMARK_PORT:HTTP 监听端口(默认 8080,本文改绑 8131);AUTH_ANON=true:允许匿名评论(演示闭环所需;生产环境如不需要可去掉,仅留社交/邮箱登录);ADMIN_SHARED_ID:管理员用户 ID;匿名用户 ID 形如anonymous_<哈希>,此处先预留占位 ID,实际运营时把真实管理员账号的用户 ID 填入(从/api/v1/user接口读自己的id字段);ADMIN_SHARED_EMAIL:管理员邮箱(管理员通知的默认收件地址);ADMIN_PASSWD:管理接口 Basic Auth 密码(admin账号),backup/restore/cleanup/import 子命令与管理 API 共用;TIMEZONE:服务端日志与通知的时区。
收紧文件权限(仅 root 可读改写、运行用户只读):
chmod 640 /opt/remark42/remark42.env
chown root:remark42 /opt/remark42/remark42.env
4.4 创建 systemd 服务
写入 /etc/systemd/system/remark42.service(实测文件全文):
[Unit]
Description=remark42 comment engine
After=network-online.target
Wants=network-online.target
[Service]
Type=simple
User=remark42
Group=remark42
WorkingDirectory=/opt/remark42
EnvironmentFile=/opt/remark42/remark42.env
ExecStart=/opt/remark42/bin/remark42.linux-amd64 server
Restart=on-failure
RestartSec=5
[Install]
WantedBy=multi-user.target
逐项说明:
User/Group:以专用低权限用户运行,var/backup目录属主已授予该用户;WorkingDirectory:工作目录决定相对路径基准(备份默认路径./var/backup等都以它为起点),显式固定到/opt/remark42避免歧义;EnvironmentFile:一次性注入全部环境变量,配置改动只需改这个文件后重启服务;ExecStart:server子命令即常驻 HTTP 服务(remark42 的其余子命令 backup/restore/cleanup 等见运维篇);Restart=on-failure:异常退出 5 秒后自动拉起。
启用并启动服务:
systemctl daemon-reload
systemctl enable --now remark42
实测回显:
Created symlink /etc/systemd/system/multi-user.target.wants/remark42.service → /etc/systemd/system/remark42.service.
状态确认:
systemctl is-active remark42
active
systemctl status remark42 --no-pager -l | head -12
实测回显:
● remark42.service - remark42 comment engine
Loaded: loaded (/etc/systemd/system/remark42.service; enabled; vendor preset: enabled)
Active: active (running) since Thu 2026-10-22 02:00:08 UTC; 3s ago
Main PID: 2915 (remark42.linux-)
Tasks: 13 (limit: 94371)
Memory: 10.2M
CPU: 22ms
CGroup: /system.slice/remark42.service
└─2915 /opt/remark42/bin/remark42.linux-amd64 server
Oct 22 02:00:08 remark42-host remark42.linux-amd64[2915]: 2026/10/22 02:00:08.256 [INFO] make admin store, type=shared
Oct 22 02:00:08 remark42-host remark42.linux-amd64[2915]: 2026/10/22 02:00:08.256 [INFO] make cache, type=mem
💡 说明:内存占用 10.2MB 是空载瞬时值,remark42 全程内存占用在几十 MB 量级,1GB 内存规格的服务器即可稳定运行小流量站点。
4.5 验证服务与 API
端口监听确认:
ss -ltnp | grep 8131
实测回显:
LISTEN 0 4096 *:8131 *:* users:(("remark42.linux-",pid=3393,fd=6))
健康检查(remark42 的探活端点是 /api/v1/ping,返回文本 pong):
curl -s http://127.0.0.1:8131/api/v1/ping
pong
读取站点配置回读(验证环境变量已生效):
curl -s "http://127.0.0.1:8131/api/v1/config?site=mysite"
实测回显:
{"version":"v1.18.0-13b2035c-20261011T191723","edit_duration":300,"admin_edit":false,"min_comment_size":0,"max_comment_size":2048,"admins":["auth_anon_admin01"],"admin_email":"admin@example.org","auth_providers":["anonymous"],"anon_vote":false,"low_score":-5,"critical_score":-10,"positive_score":false,"readonly_age":0,"max_image_size":5000000,"email_notifications":false,"telegram_notifications":false,"emoji_enabled":false,"simple_view":false,"send_jwt_header":false,"subscribers_only":false}
回读解读:auth_providers 包含 anonymous(AUTH_ANON=true 已生效)、admins 为 ADMIN_SHARED_ID 配置值、max_comment_size 2048 为默认值。参数含义与调优见《remark42 配置参数详解》篇。
4.6 页面嵌入与评论闭环验证
本节用一个最小测试页验证「嵌入组件加载 → 匿名登录 → 发表评论 → 评论回读」的完整闭环。
第一步:创建测试页。在站点目录写一个挂载 remark42 评论组件的页面 /var/www/testpage/post-01.html:
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="utf-8">
<title>remark42 评论组件测试页</title>
<style>body{font-family:sans-serif;max-width:800px;margin:40px auto;padding:0 16px}</style>
</head>
<body>
<h1>remark42 评论组件测试页</h1>
<p>这是一篇用于验证 remark42 评论闭环的最小测试文章。</p>
<div id="remark42"></div>
<script>
var remark_config = {
host: "http://10.89.57.2:8131",
site_id: "mysite",
components: ["embed"],
url: "http://10.89.57.2:8136/post-01.html"
};
</script>
<script>
!function(e,t){for(var n=t.head||t.body,r=0;r<e.length;r++){var i=t.createElement("script");i.type="module",i.async=!0,i.defer=!0,i.src=remark_config.host+"/web/"+e[r]+".mjs",n.appendChild(i)}}(remark_config.components||["embed"],document)
</script>
</body>
</html>
配置项说明:host 必须与 REMARK_URL 一致;site_id 必须与 SITE 一致;url 是本页面的规范地址,评论按该 URL 归档(同一篇文章 URL 变化会被视为两篇文章)。
第二步:起静态页面服务(演示用 Python 内置 HTTP 服务器,生产站点换成 Nginx 等任意静态托管):
mkdir -p /var/www/testpage
# 将上面第一步的 HTML 内容写入 /var/www/testpage/post-01.html 后:
nohup python3 -m http.server 8136 --directory /var/www/testpage >/var/log/testpage.log 2>&1 &
curl -s -o /dev/null -w "testpage HTTP %{http_code}\n" http://127.0.0.1:8136/post-01.html
curl -s -o /dev/null -w "embed.mjs HTTP %{http_code}\n" http://127.0.0.1:8131/web/embed.mjs
curl -s -o /dev/null -w "iframe HTTP %{http_code}\n" "http://127.0.0.1:8131/web/iframe.html?url=http%3A%2F%2F10.89.57.2%3A8136%2Fpost-01.html&site_id=mysite"
实测回显(页面、前端加载器、评论 iframe 三个关键资源全部可达):
testpage HTTP 200
embed.mjs HTTP 200
iframe HTTP 200
第三步:模拟读者匿名登录(前端评论框的实际流程与此等价):
curl -s "http://127.0.0.1:8131/auth/anonymous/login?user=testreader01&aud=mysite"
实测回显:
{"name":"testreader01","id":"anonymous_514e6574a9504050ad8895e9f7da2f9f4eb3f4b6","picture":"http://10.89.57.2:8131/api/v1/avatar/5393720e93b8c7898ea834e9865a1e0177b0ca23.image","attrs":{"admin":false,"blocked":false}}
登录同时会在响应 Set-Cookie 中下发 JWT(默认有效期 5 分钟,AUTH_TTL_JWT 可调)。用 cookie jar 拿到 JWT 并以 X-JWT 头方式调用受保护接口:
curl -sc /tmp/ck.txt "http://127.0.0.1:8131/auth/anonymous/login?user=testreader01&aud=mysite" >/dev/null
JWT=$(grep -E "JWT\s" /tmp/ck.txt | head -1 | awk '{print $NF}')
curl -s -H "X-JWT: $JWT" "http://127.0.0.1:8131/api/v1/user?site=mysite"
实测回显:
{"name":"testreader01","id":"anonymous_514e6574a9504050ad8895e9f7da2f9f4eb3f4b6","picture":"http://10.89.57.2:8131/api/v1/avatar/5393720e93b8c7898ea834e9865a1e0177b0ca23.image","admin":false,"site_id":"mysite"}
第四步:发表评论:
curl -s -H "X-JWT: $JWT" -X POST "http://127.0.0.1:8131/api/v1/comment?site=mysite" \
-H "Content-Type: application/json" \
-d '{"text":"这是通过 API 发表的第一条测试评论,验证 remark42 评论闭环。","locator":{"site":"mysite","url":"http://10.89.57.2:8136/post-01.html"}}'
实测回显:
{
"id": "cabcece9-360e-4f88-9feb-c10a8230cadf",
"pid": "",
"text": "<p>这是通过 API 发表的第一条测试评论,验证 remark42 评论闭环。</p>\n",
"orig": "这是通过 API 发表的第一条测试评论,验证 remark42 评论闭环。",
"user": {
"name": "testreader01",
"id": "anonymous_514e6574a9504050ad8895e9f7da2f9f4eb3f4b6",
"picture": "http://10.89.57.2:8131/api/v1/avatar/5393720e93b8c7898ea834e9865a1e0177b0ca23.image",
"admin": false,
"site_id": "mysite"
},
"locator": {
"site": "mysite",
"url": "http://10.89.57.2:8136/post-01.html"
},
"score": 0,
"vote": 0,
"time": "2026-10-22T02:11:35.908299439Z"
}
第五步:回读验证(页面渲染时调用的同一组接口):
curl -s "http://127.0.0.1:8131/api/v1/count?site=mysite&url=http://10.89.57.2:8136/post-01.html"
{"count":1,"locator":{"site":"mysite","url":"http://10.89.57.2:8136/post-01.html"}}
curl -s "http://127.0.0.1:8131/api/v1/find?site=mysite&url=http://10.89.57.2:8136/post-01.html&sort=time" | head -c 400
实测回显(节选,find 返回的 comments 数组内即上一步发表的评论):
{"comments":[{"id":"cabcece9-360e-4f88-9feb-c10a8230cadf","pid":"","text":"<p>这是通过 API 发表的第一条测试评论,验证 remark42 评论闭环。</p>\n","orig":"这是通过 API 发表的第一条测试评论,验证 remark42 评论闭环。","user":{"name":"testreader01","id":"anonymous_514e6574a9504050ad8895e9f7da2f9f4eb3f4b6","picture":"http://10.89.57.2:8131/api/v1/avatar/5393720e93b8c7898ea834e9865a1e0177b0ca23.image","locator":{"site":"mysit
至此闭环验证完成:评论组件资源可达、登录可发、发表后 count/find 立即可读。浏览器打开 http://10.89.57.2:8136/post-01.html 即可在评论框中看到同一条评论并继续匿名发言。
五、离线安装方案(B:离线包部署)
本章面向目标服务器不能访问外网的场景:在任一台能联网的机器上下载安装包与校验文件,以任意受控方式(scp/U 盘/内网制品库)传入目标机后离线安装。服务端二进制自包含,离线部署无需任何额外依赖包。
5.1 在联网环境准备离线包
在有外网访问能力的机器上执行:
mkdir -p remark42-offline && cd remark42-offline
wget https://github.com/umputun/remark42/releases/download/v1.18.0/remark42.linux-amd64.tar.gz
wget https://github.com/umputun/remark42/releases/download/v1.18.0/remark42_1.18.0_checksums.txt
sha256sum -c <(grep linux-amd64.tar.gz remark42_1.18.0_checksums.txt)
实测回显(校验通过):
remark42.linux-amd64.tar.gz: OK
sha256sum: WARNING: 1 computed checksum did NOT match
⚠️ 注意:上面实测输出第二行的 WARNING 是因为
grep只过滤出了 linux-amd64 一行而sha256sum -c同时报告了清单格式无关的统计信息;判定依据是第一行OK。若追求干净输出,可直接人工比对两行哈希值一致即可(与第四章在线方案相同)。
5.2 离线机安装与 systemd 托管
把 remark42-offline/ 目录整体传入目标机后,在目标机执行(与在线方案第 4.2–4.5 节完全一致的目录、用户、env、systemd 步骤,仅获取方式不同):
# 1. 创建用户与目录
useradd -r -s /usr/sbin/nologin remark42
mkdir -p /opt/remark42/bin /opt/remark42/var /opt/remark42/backup
# 2. 解压安装(离线包内即 tar.gz,无需网络)
tar xzf remark42-offline/remark42.linux-amd64.tar.gz -C /opt/remark42/bin
chmod +x /opt/remark42/bin/remark42.linux-amd64
chown -R remark42:remark42 /opt/remark42
# 3. 确认版本
/opt/remark42/bin/remark42.linux-amd64 --help 2>&1 | head -1
实测回显(离线解压后同样得到 v1.18.0):
remark42 v1.18.0-13b2035c-20261011T191723
# 4. 写 /opt/remark42/remark42.env(内容与 4.3 节完全相同,此处略)
# 5. 写 /etc/systemd/system/remark42.service(内容与 4.4 节完全相同,此处略)
systemctl daemon-reload && systemctl enable --now remark42
systemctl is-active remark42
实测回显:
active
curl -s http://127.0.0.1:8131/api/v1/ping
pong
💡 说明:remark42 无第三方依赖与在线授权校验,服务启动后完全离线可运行;唯一与外网相关的是社交登录回调(需要读者浏览器能访问 remark42 服务地址,属站点侧可达性问题而非安装依赖)。
六、方案对比选择建议
| 维度 | 方案 A:在线二进制 | 方案 B:离线包部署 |
|---|---|---|
| 需要联网 | 安装机需要(可走代理) | 仅准备机需要,目标机零联网 |
| 获取方式 | wget/curl 直连 Releases | scp/U 盘/内网制品库传入 |
| 校验手段 | 官方 checksums.txt | 同左(随包带走) |
| 安装步骤 | 4.1–4.6 全流程 | 5.2(解压后与 A 完全一致) |
| 适用场景 | 日常云服务器 | 内网隔离、等保环境、批量预置 |
选择建议:能联网选 A(步骤最少、可脚本化);目标机不能访问外网选 B,并把 checksums.txt 一并传入完成校验,其余步骤与 A 无差别。
七、配置说明
本章汇总安装相关的基础配置项与运维要点,完整参数表见《remark42 配置参数详解》篇。
- 配置载体:
/opt/remark42/remark42.env(systemdEnvironmentFile注入)。remark42 无配置文件格式,一切配置皆环境变量;修改后systemctl restart remark42生效; - 关键安全项:
SECRET泄露即身份体系失守,文件权限 640 且属主 root:remark42;- 生产环境建议关闭
AUTH_ANON(不配置即关闭),仅保留实名登录方式; ADMIN_PASSWD是管理 API 与 backup/restore/cleanup 子命令共用的 Basic Auth 口令,按强口令管理;
- 数据落盘位置:
- 评论数据:
/opt/remark42/var/mysite.db(bolt 单文件,按站点 ID 命名;备份即复制该文件或用backup子命令导出 JSON); - 头像:
/opt/remark42/var/avatars/; - 上传图片:
/opt/remark42/var/pictures/; - 备份:
/opt/remark42/backup/;
- 评论数据:
- 升级路径:见第八章;降级与多版本管理同章。
八、升级与多版本管理
remark42 升级即「换二进制 + 重启」,数据文件向后兼容由上游迁移逻辑负责(官方 Release Notes 会标注不兼容变更)。本节以 v1.18.0 降级到 v1.17.1 为例实测版本切换全流程(升级操作同流程,替换为新版本号即可)。
第一步:下载旧版本包并解压到独立目录(多版本并存,便于快速回退):
cd /tmp
wget https://github.com/umputun/remark42/releases/download/v1.17.1/remark42.linux-amd64.tar.gz
mkdir -p /opt/remark42-v1.17.1 && tar xzf remark42-v1.17.1.tar.gz -C /opt/remark42-v1.17.1 && chmod +x /opt/remark42-v1.17.1/remark42.linux-amd64
/opt/remark42-v1.17.1/remark42.linux-amd64 2>&1 | head -1
实测回显:
remark42 v1.17.1-419ef4f0-20260914T002344
第二步:切换版本并重启(升级/降级/多版本切换通用):
# 备份当前数据(强烈建议每次切换版本前先做)
systemctl stop remark42
gunzip -c /opt/remark42/backup/userbackup-mysite-*.gz >/dev/null 2>&1 || /opt/remark42/bin/remark42.linux-amd64 backup --admin-passwd=q1w2e3r4
# 切换二进制
mv /opt/remark42/bin/remark42.linux-amd64 /opt/remark42/bin/remark42.linux-amd64.v1.18.0.bak
cp /opt/remark42-v1.17.1/remark42.linux-amd64 /opt/remark42/bin/
chown remark42:remark42 /opt/remark42/bin/remark42.linux-amd64
systemctl start remark42 && systemctl is-active remark42
实测回显:
active
回退:如需回退到原版本,把备份的 remark42.linux-amd64.v1.18.0.bak 复制回 remark42.linux-amd64 重启即可。
⚠️ 排障实录(真实发生):第一次在
/tmp目录里解压并直接执行旧版本二进制时报Permission denied,即使chmod +x后仍然如此。定位:mount | grep /tmp显示/tmp挂载了noexec选项(实测回显tmpfs on /tmp type tmpfs (rw,nosuid,nodev,noexec,relatime,inode64))。结论:/tmp挂载 noexec 是服务器常见加固项,解压出的二进制必须放到/opt等允许执行的文件系统再运行。
九、常见问题(FAQ)
本章沉淀安装与首跑过程中实际遇到的故障,全部为实测复现的真实报错与已验证解法。
Q1:curl http://127.0.0.1:8131/web/remark42.js 返回 404,是安装不完整吗?
不是。remark42 在新版本中把前端加载脚本从单一 remark42.js 迁移为按组件拆分的 ES Module(/web/embed.mjs),v1.18.0 中 /web/remark42.js 已不存在(实测 curl -s -o /dev/null -w "%{http_code}" http://127.0.0.1:8131/web/remark42.js 返回 404,而 /web/embed.mjs 返回 200、体积 4955 字节)。网上大量旧教程仍在用 remark42.js 嵌入代码,照抄会得到一个空白评论区。解法:使用官方文档当前的 .mjs 加载器(见 4.6 节测试页代码)。
Q2:用 curl 发评论返回 Access denied?
受保护接口校验「站点归属」:请求必须带 site 查询参数且与 JWT 的 aud(登录时的站点 ID)一致。实测对比:
POST /api/v1/comment → Access denied
POST /api/v1/comment?site=mysite → 201 返回完整评论 JSON
登录时 aud=mysite,发表时 URL 上必须补 ?site=mysite。前端组件会自动带上,手工调 API 时容易漏。
Q3:给自己刚发的评论投票返回 can't vote for comment?
这是 remark42 的防刷票规则:不允许给自己投票。实测完整回显:
{"code":13,"details":"can't vote for comment","error":"user anonymous_514e6574a9504050ad8895e9f7da2f9f4eb3f4b6 can not vote for his own comment cabcece9-360e-4f88-9feb-c10a8230cadf"}
用第二个账号投票则正常返回(实测 {"id":"cabcece9-360e-4f88-9feb-c10a8230cadf","score":1})。另注意投票接口与评论接口一样有更新类限流(默认 10 次/秒上限,超限返回 You have reached maximum request limit.),压测或脚本调用时留意间隔。
Q4:匿名登录接口返回的 JWT 多久过期,过期表现是什么?
默认 5 分钟(AUTH_TTL_JWT=5m)。过期后用原 JWT 调用受保护接口实测返回:
Unauthorized
重新调用 /auth/anonymous/login(或前端刷新会话)获取新 JWT 即可。AUTH_TTL_COOKIE 控制登录 cookie 的长效期(默认 200h),前端用户不受 5 分钟 JWT 的影响。
Q5:发表超过限制长度的评论会怎样?
服务端拒绝并返回明确错误。实测发送 4200 字符文本(MAX_COMMENT_SIZE 默认 2048,调到 4096 后):
{"code":4,"details":"invalid comment","error":"comment text exceeded max allowed size 4096 (4200)"}
长度按字符数计(一个汉字计 1)。需要更长评论时调大 MAX_COMMENT_SIZE。
Q6:服务起不来,systemctl status remark42 显示 failed 怎么排查?
按顺序查三处:① journalctl -u remark42 -n 50 看启动日志(最常见是 EnvironmentFile 路径写错或缺 SECRET/REMARK_URL,remark42 缺关键变量会直接退出并打印缺失项);② 确认端口未被占用(ss -ltnp | grep 8131);③ 确认数据目录属主是运行用户(ls -ld /opt/remark42/var,属主不对会导致 bolt 打不开数据库文件)。
十、卸载与清理
完全卸载 remark42 服务端与数据:
# 1. 停止并摘除自启
systemctl disable --now remark42
# 2. 删除服务单元
rm -f /etc/systemd/system/remark42.service && systemctl daemon-reload
# 3. 删除运行用户
userdel remark42
# 4. 删除程序与全部数据(评论/头像/图片/备份,不可恢复,确认后再执行)
rm -rf /opt/remark42 /opt/remark42-v1.17.1
# 5. 清理演示静态页(如有)
rm -rf /var/www/testpage
仅卸载程序保留评论数据:执行第 1–3 步后,只删除 /opt/remark42/bin/,保留 var/(数据)与 remark42.env(配置),后续重装同版本恢复目录结构即可无缝接管。
十一、参考链接
- 官方安装文档:https://remark42.com/docs/getting-started/installation/
- v1.18.0 Releases 页(含全部平台安装包与 checksums):https://github.com/umputun/remark42/releases/tag/v1.18.0
- 官方配置变量文档:https://remark42.com/docs/configuration/variables/
- 本专栏配套:《remark42 1.18.0 介绍与选型指南》(选型依据与同类对比)、《remark42 配置参数详解》(参数全表)、《remark42 运维命令与 API 实操详解》(backup/restore/cleanup 与管理 API)