# 阅读服务器版搭建

https://github.com/hectorqin/reader

阅读 3 服务器版,搭建在服务器上用浏览器使用阅读,再也不挑设备啦,原生支持多设备😀

# docker 启动!

# 自用版(建议修改映射端口)
docker run -d --restart=always --name=reader -e "SPRING_PROFILES_ACTIVE=prod" -v $(pwd)/logs:/logs -v $(pwd)/storage:/storage -p 8080:8080 hectorqin/reader
# 多用户版(建议修改映射端口)
docker run -d --restart=always --name=reader -v $(pwd)/logs:/logs -v $(pwd)/storage:/storage -p 8080:8080 hectorqin/reader java -jar /app/bin/reader.jar --spring.profiles.active=prod --reader.app.secure=true --reader.app.secureKey=管理密码 --reader.app.inviteCode=注册邀请码
# 多用户版 使用环境变量(建议修改映射端口)
docker run -d --restart=always --name=reader -e "SPRING_PROFILES_ACTIVE=prod" -e "READER_APP_SECURE=true" -e "READER_APP_SECUREKEY=管理密码" -e "READER_APP_INVITECODE=注册邀请码" -v $(pwd)/logs:/logs -v $(pwd)/storage:/storage -p 8080:8080 hectorqin/reader

下面你就可以访问 http://ip:8080 使用阅读了,如果你希望使用域名,可以使用 nginx/caddy 等服务反代本地 8080 端口

# jar 部署

作者在 releases 页发布了用于服务器的 jar 包,我们可以借此部署(适用于无 root 权限 ordocker 禁用等情况)

# 安装 jdk 环境

centos 系统

#命令查找java版本
yum search java|grep jdk
#这里我们选择java-11-openjdk-devel.x86_64
yum install java-11-openjdk-devel.x86_64 -y
#验证是否安装成功
java -version

debian/ubuntu 系统

#下载Oracle java23
wget https://download.oracle.com/java/23/latest/jdk-23_linux-x64_bin.deb
# 若链接失效或者需要其它版本java可以访问 https://www.oracle.com/cn/java/technologies/downloads/ 获取最新下载链接
#安装
sudo dpkg -i jdk-23_linux-x64_bin.deb

# 部署

下载最新版压缩包

# 使用GitHub API获取最新的发行版信息(里边有最新的版本号标识)
response=$(curl -s https://api.github.com/repos/hectorqin/reader/releases/latest)
# 提取下载链接 (tag_name属性即为版本号属性 cut命令获取版本号属性的值 awk命令把版本号中的v字符删除)
version=$(echo "$response" | grep 'tag_name' | cut -d'"' -f4 | awk '{print substr($0, 2, length($0) - 1)'})
# 拼接下载连接
download_url=https://github.com/hectorqin/reader/releases/download/v$version/reader-server-$version.zip
# 使用curl下载最新发行版(-L意思是支持重定向,很多下载都是重定向下载  -o是自定义名字)
curl -L -o reader.zip $download_url

解压并运行

# 解压文件
unzip reader.zip
#重命名jar文件
mv target/reader-pro-$version.jar target/reader.jar
# 运行
./bin/startup.sh
# windows 上直接点击 bin/startup.cmd 文件
# startup 脚本支持以下选项,这些选项如果使用命令行参数修改,则会覆盖配置文件的设置
# -m single|multi 选择单用户/多用户模式,默认 以配置文件 conf/application.properties 为准
# -s reader-xx 选择 jar 文件名(不含.jar后缀),默认使用target目录里最新的jar
# -i inviteCode 设置多用户模式下的邀请码,默认 以配置文件 conf/application.properties 为准
# -k secureKey 设置多用户模式下的管理密码,默认 以配置文件 conf/application.properties 为准
# 注意!!!startup 脚本在单用户模式下 默认占用 256m 内存,在多用户模式下 默认占用 1g 内存,如果内存不够,请自行修改脚本
# web端 http://localhost:8080/
# 接口地址 http://localhost:8080/reader3/

同样的,到此已经可以访问 ip:8080 使用了,如果想使用域名访问还可以使用 nginx/caddy 的反代

# 白嫖部署实战

# azure 上 app service 部署

azure 作为巨硬家的产业,提供的额度和服务都是很大方的,我们这里用到的 app service 服务就是属于永久免费服务中的一项

# 新建应用

登录 azure 账号后搜索应用程序服务或者点击传送门直达

进入面板后点击创建 web 应用

填写如图示例,新建资源组以及应用程序名称可以随意填写;防止被反撸,注意需要切换定价计划为免费 F1,并且这里的免费定价层对于部署个人使用的阅读服务器来说是绰绰有余的;地区可以自行选择,但是推荐选择延迟更低的地区,可以通过这个工具来测试自己到不同地区数据中心的延迟在进行选择。

然后切换到容器选项卡

复制下面的内容保存为 yml 文件上传至配置文件(此时你可以修改文件中的环境变量,以决定是否启用多用户,这里我没有启用多用户配置)

version: '3.1'
services:
  reader:
    image: hectorqin/reader 
    container_name: reader 
    restart: always
    ports:
      - 8080:8080
    volumes:
      - ${WEBAPP_STORAGE_HOME}/logs:/logs
      - ${WEBAPP_STORAGE_HOME}/storage:/storage
    environment:
      - SPRING_PROFILES_ACTIVE=prod
      - READER_APP_CACHECHAPTERCONTENT=true 
      - READER_APP_SECURE=false

这里需要注意的是 volumes 的映射中必须使用 ${WEBAPP_STORAGE_HOME} 目录下才能实现数据持久化,不然 azure 在重启你的应用时会丢失你的所有数据,实测使用监控保活也会出现数据丢失的情况。(在 azure 文档中写明的持久化目录是 /home,但是实测并不行,需要使用 ${WEBAPP_STORAGE_HOME}

接下来就可以选择屏幕左下角查看 + 创建,或者直接点查看 + 创建选项卡,再选择创建

# 变量设置

部署完成后切换到应用面板 - 环境变量

修改 WEBSITES_ENABLE_APP_SERVICE_STORAGE 变量值为 true

WEBSITES_PORT 变量值为 8080

# 持久化

尽管上面已经将数据映射至 ${WEBAPP_STORAGE_HOME} 目录,但 azure 不会自动创建文件夹,此时直接启动会发生失败,所以我们需要手动创建文件夹

选择 高级工具 - 转到

然后在新转到的网页 url 中最后加上一个 /newui

再选择左侧边栏的 fileManager 转到文件管理器,此时的目录就在 ${WEBAPP_STORAGE_HOME} 下,我们需要在此新建 logs 和 storage 两个文件夹,可以采用在本地新建文件夹后往里随便放一个文件,然后拖动整个文件夹上传达到新建文件夹的目的

# 重启应用

接下来,回到你的应用面板重启应用,一个服务器版的阅读就部署好了

最后点击 azure 给你的默认域进入网页,注意保管好你的网址不要泄露给他人

# serv00(不推荐)

得益于 java 优秀的跨平台性,我们可以直接在 serv00 的 FreeBSD 系统上运行阅读服务器版的 jar 文件,但是在 serv00 上部署

GitHub - hectorqin/reader

为不推荐的方案,原因是虽然可以部署,但是运行会超出内存限制,不知道 serv00 官方是否会封号操作,如果确定使用本方案,请务必做好数据备份!!

# 创建 serv00 账号

serv00 的申请地址为 https://www.serv00.com/,注意拒绝大陆 ip 注册,同时实测 outlook 邮箱接收不到邮件,并且拒绝 gmail 别名邮箱,这里推荐使用 https://mail.proton.me/ 进行注册操作,注册后会收到 serv00 的连接信息。

# 部署项目

# 面板操作

Additional services 选项卡中找到 Run your own applications 项目,将其设置为 Enabled 即可。如果不开启这一项,自己的用户目录下的所有文件都无法添加可执行权限。

Port reservation 中放行一个 tcp 端口并记住这个端口备用

WWW Websites 使用 Add website 功能新建一个 Node.js 类型的网站,可删除原来的 xxx.serv00.net 并重新使用 xxx.serv00.net,这里也可以填入自己的域名。建议使用托管在 cloudflare 上的域名,后续如果该 server 的 IP 被墙我们可以使用 cf 提供的 cdn 拯救网站。若使用 *.xxx.serv00.net 的域名就不需要更多操作了,但如果是自己的域名,则需要将自己的域名解析至该 server 的 ip,IP 可以在 SSL-WWW Websites 选项卡看到,两个 IP 任选其一即可


添加完新站点后,继续点击上方的 Manage SSL certificates ,接着在出口 IP 的右侧点击 Manage ,再点击 Add certificate

TypeDomain
Generate Let’s Encrypted certificate与刚刚添加的站点域名保持一致(如果是原有的 USERNAME.serv00.net ,可以省略此步)

如果使用的 server 的出口 IP 已经被墙,建议使用 cloudflare 托管的域名,此时可以开启小黄云拯救被墙的 serv00

# SSH 操作

进入 nodejs 的工作目录:

cd ~/domains/网站/public_nodejs

下面运行

response=$(curl -s https://api.github.com/repos/hectorqin/reader/releases/latest)
version=$(echo "$response" | grep 'tag_name' | cut -d'"' -f4 | awk '{print substr($0, 2, length($0) - 1)'})
download_url=https://github.com/hectorqin/reader/releases/download/v$version/reader-server-$version.zip
curl -L -o reader.zip $download_url
unzip reader.zip
mv target/reader-pro-$version.jar target/reader.jar
rm reader.zip

此时打开面板中 File manager 选项卡 进入 domains / 网站 /public_nodejs/conf 目录,打开 application.properties 文件修改最下面的 reader 服务监听端口为你刚刚放行的端口
回到 ssh,执行./bin/startup.sh -m single,没有出现报错即可以使用 ctrl+c 停止运行

# 保活操作

本方法使用 saika 大佬保活方案,详见大佬文章

仍在 /domains/ 网站 /public_nodejs 目录下,删除 public_html 文件夹,在目录下新建 app.js 和 package.json

app.js 的内容如下:

const express = require("express");
const app = express();
const port = 3000;
var exec = require("child_process").exec;
const { createProxyMiddleware } = require("http-proxy-middleware");
const path = require('path');
const fs = require('fs');
const currentDir = __dirname;
process.chdir(currentDir);
app.use('/', createProxyMiddleware({
  target: 'http://127.0.0.1:PORT', // 改成 reader 实际运行端口
  changeOrigin: true,
  ws: true, 
  onError: (err, req, res) => {
    res.writeHead(500, {
      'Content-Type': 'text/plain',
    });
    res.end('Please wait for a while and try to refresh the page.');
  },
}));
function keep_web_alive() {
    exec("pgrep -laf reader", function (err, stdout, stderr) {
      if (stdout.includes("reader")) {
        console.log("web 正在运行");
      } else {
        exec(
          "cd ~/domains/网站/public_nodejs && ./bin/startup.sh -m single &",
          function (err, stdout, stderr) {
            if (err) {
              console.log("保活-调起web-命令行执行错误:" + err);
            } else {
              console.log("保活-调起web-命令行执行成功!");
            }
          }
        );
      }
    });
  }
  setInterval(keep_web_alive, 10 * 1000);
app.listen(port, () => console.log(`Example app listening on port ${port}!`));

注意修改第 13 和 30 行中端口和目录

package.json 的内容如下:

{
    "name": "example",
    "version": "1.0.0",
    "description": "A simple Express.js server",
    "author": "k0baya",
    "main": "app.js",
    "license": "MIT",
    "private": false,
    "scripts": {
      "start": "node app.js"
    },
    "dependencies": {
      "express": "^4.19.2",
      "http-proxy-middleware": "^3.0.0"
    },
    "engines": {
      "node": "22"
    },
    "keywords": [
      "node"
    ]
  }

再次回到 ssh 窗口,仍在本目录下先执行 npm22 install ,再访问网页即可唤醒应用。监控网页即可对应用进行保活。

# 续期操作

在面板 Cron job 内添加每个月一次的 sshpass 命令

sshpass -p '密码' ssh -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null -tt 用户名@地址 "exit"

# 书源

这里最后再分享一个书源 https://github.com/aoaostar/legado/raw/release/cache/3fc2c64c5489c491de6284dca2c2dfce7f551bc9.json

国内服务器可以用 https://mirror.ghproxy.com/https://github.com/aoaostar/legado/raw/release/cache/3fc2c64c5489c491de6284dca2c2dfce7f551bc9.json

最后的最后还有一个网站源仓库

# 完结撒花,开启阅读之旅!