分类目录: 移动互联

HomeServer安装在线Office:Docker安装最新精简版OnlyOffice

最近从这个帖子看到一些有趣的企业软件,其中有一个在线办公软件OnlyOffice,感觉挺有意思的。之前一直为各种自建网盘无法打开Office文档而烦恼,看到FileRun可以集成OnlyOffice DocumentServer,于是就决定开始搭建这个,解决自建网盘直接预览和编辑文档的问题。目前在用的3款网盘软件,还只发现FileRun支持,其他几款如FileBrowser、Cloudreve都还不支持。FileBrowser的Git库上面,有人提交了PR,但是迟迟没有被approve和合入。看起来挺简单的集成功能,不清楚开源owner为什么不合入。

第三方提供的界面总归还是有些不够专业,于是想着自己搭建一个完整的在线Office。经过一番摸索,需要DocumentServer+CommunityServer配合。前者只是一个文档查阅和编辑器,后者提供UI管理文档。当然也可以仅仅只搭建DocumentServer,用第三方的UI来集成,FileRun就算,还有更多的,笔者并没有作更多探索。这里的CommunityServer是一个复杂的办公Workspace,包括一系列的复杂的项目管理、团队管理等套件,这些套件全部包含在内,显得整个docker非常臃肿,资源有限的HomeNAS难以支撑,于是针对这个CommunityServer又做了一些裁剪,主要是把一些感觉用不到的进程停掉了,自己做了docker镜像,也上传到了dockerhub上面。下面开始介绍这两个组件的安装配置过程。

DocumentServer搭建很简单,毕竟依赖的组件少,官方docker镜像也非常简洁,很快就按照官方给的安装命令在HomeNAS上面跑起来了,并且简单配置之后就能在FileRun上面直接查阅和编辑Office文档了。但是发现一个问题,就是DocumentServer为了确保安全,默认启用了jwt_token。token确实有用,可以避免DocumentServer被盗用,被任意其他网络服务拿去使用耗费有限的资源,因此token是UI和Server之间通信的安全保障。有一个问题是,DocumentServer的jwt_token在每次DS重启之后就会重新生成,这样FileRun上面又要重新设置,经过分析,可以用Docker的环境变量指定一个固定的token。然后,如果没有指定外部DB,则DocumentServer会自己启动一个内建的mysql,这个mysql与已有的外部的mysql重复了,没必要,因此我选择使用外部的mysql来公用,节省资源。最终具体的运行命令如下:

docker run –net onlyoffice –name onlyoffice-document-server -d -p 127.0.0.1:12583:80 \
-e DB_TYPE=mysql \
-e DB_HOST=IP_OF_YOUR_DB_HOST \
-e DB_PORT=3306 \
-e DB_NAME=onlyoffice \
-e DB_USER=USERNAME_OF_YOUR_DB \
-e “DB_PWD=PASSWORD_OF_YOUR_DB” \
-e JWT_ENABLED=true \
-e “JWT_SECRET=YOUR_FIX_JWT_TOKEN” \
-v /your/app/path/DocumentServer/logs:/var/log/onlyoffice  \
-v /your/app/path/DocumentServer/data:/var/www/onlyoffice/Data \
onlyoffice/documentserver:latest

上面只开启DS的http端口,同样使用系统统一的一个Nginx反向代理HTTPS对外提供服务。docker启动后,占用的资源非常少。具体的进程列表如下:

document-server

CommunityServer的安装过程就比较坎坷了,主要是想禁用多个暂时不需要的服务,笔者这里主要禁用elasticsearch、内部自带的mysql、还有一堆的Soauth、API、迁移数据、自动清理数据、备份数据、Chat服务等,感觉对于只想体验一下在线Office而言,这些都用不上,禁止之后也没有发现有什么地方运行异常,只用修改run-community-server.sh这个文件,然后重新打镜像即可。如果不做这个裁剪,我的四核6100T的CPU,16G内存,都非常吃力,并且还频繁崩溃重启。最终精简版的进程列表如下:

community-server

修改后的镜像我也上传到了,自己的dockerhub账号下:

https://hub.docker.com/repository/docker/shentar/onlyoffice-community-server

docker pull shentar/onlyoffice-community-server:latest

CommunityServer要使用token访问DocumentServer时,有点坑,找遍了各种设置界面都没看到,网上也没有任何资料介绍,最终在官方给的docker安装脚本中找到了,也是通过一个环境变量来指定。这样只要将该变量指定为DS的token即可。需要注意的是,CommunityServer也有自己的jwt_token,因此这两个都要指定,才能正常运转。具体的环境变量名为:

DOCUMENT_SERVER_JWT_ENABLED
DOCUMENT_SERVER_JWT_SECRET

最终,安装CommunityServer的命令为:

docker run –net onlyoffice -i -t -d –privileged –restart=always \
–name onlyoffice-community-server -p 127.0.0.1:12555:80 \
-e “MYSQL_SERVER_ROOT_PASSWORD=YOUR_MYSQL_PASSWORD” \
-e MYSQL_SERVER_DB_NAME=onlyoffice \
-e MYSQL_SERVER_HOST=YOUR_MYSQL_HOST \
-e MYSQL_SERVER_USER=YOUR_MYSQL_USERNAME \
-e “MYSQL_SERVER_PASS=YOUR_MYSQL_PASSWORD” \
-e JWT_ENABLED=true \
-e “JWT_SECRET=YOUR_FIX_JWT_TOKEN” \
-e “DOCUMENT_SERVER_JWT_ENABLED=true” \
-e “DOCUMENT_SERVER_JWT_SECRET=YOUR_FIX_JWT_TOKEN” \
-v /your/app/path/CommunityServer/data:/var/www/onlyoffice/Data \
-v /your/app/path/CommunityServer/logs:/var/log/onlyoffice \
-v /your/app/path/DocumentServer/data:/var/www/onlyoffice/DocumentServerData \
-v /sys/fs/cgroup:/sys/fs/cgroup:ro \
shentar/onlyoffice-community-server:latest

同样只开启HTTP,利用外部的Nginx来实现HTTPS反向代理,省去了一大堆SSL证书相关的事情。最终运行起来的效果如下图。测试了各项基本功能,都是正常的,精简掉的那些进程暂时用不着。

在线Office

| 1 分2 分3 分4 分5 分 (5.00- 3票) Loading ... Loading ... | 同时归档在:WEB网络, 数码硬件, 软件应用 | 标签: , , , , |

开源好用的电子书管理服务Talebook(Calibre网络版)安装使用指南

今天是世界读书日,介绍一款已经用过一段时间的电子书在线管理、阅读服务。Talebook是一个开源的Calibre WEB外壳,源项目地址是:Github项目,我为了方便自己开发,在自己的代码托管服务上放了一份源码,方便存放自己的开发过程代码。也经常将自己用稳定了的特性或者修改的Bug提交MR推送到原作者的项目中。我主要会根据自己的需要开发一些特性和修复我认为比较关键的bug。代码地址为:自用Talebook地址Docker镜像地址。增加了多个特性,如:限制单个IP地址下载书籍的数量限制特性,用来防止爬虫大并发爬取书籍,导致站点不可用。另外还增加了一些统计信息和界面修改等,具体的差异点可以对比两个代码工程的获取。我也会持续跟进源项目的新特性,实时合并,也继续推送自己的修改到源项目。

更新记录列表:

  1. 支持限制单个IP地址下载数量;
  2. 支持随机推荐和最新书籍推荐手动刷新;
  3. 支持个人阅读、访问、下载和推送记录,也支持一键清除,优化历史记录页面;
  4. 新增“我的收藏”功能;
  5. 上传成功的图书即从upload目录删除,避免书籍被保存两份,浪费空间;
  6. 导入页面,在删除导入记录的同时,也删除上传到uploads目录的图书。

跟原项目一样,我也基于仓库代码生成了镜像,推送到了dockerhub,有了Docker镜像,安装使用起来就非常方便:

docker run -d --name calibre \
-p 127.0.0.1:12579:80 \
-v /media/c2/docker/calibre/data:/data \
-E TZ="Asia/Shanghai" \
shentar/talebook:latest

我这里将容器内的80端口映射到本机的内部随机端口,然后再在宿主机上面使用Nginx反向代理对外提供HTTPS服务。反向代理时,需要注意一些配置:

server {
    listen 6870 ssl http2;
    server_name book.codefine.site;
    index index.html index.htm index.php default.html default.htm default.php;
    root /any/local/path/;
 
    ssl_certificate ***********;
    ssl_certificate_key ***********;
 
    ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
    
    client_max_body_size 500M; 
 
    location / {
        proxy_pass http://127.0.0.1:12579/;
        proxy_set_header Host $http_host;
        proxy_set_header X-Forwarded-Proto $scheme;
        proxy_set_header X-Nginx-Proxy true;
        proxy_set_header X-Scheme $scheme;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection $http_connection;
    }
 
    access_log on;
}

注意这些Header必须正确设置,否则可能无法正常打开主页。 剩下的就是从网页打开宿主机的6870端口即可访问。我的宿主机是有域名的因此,我的站点的地址就是:https://book.codefine.site:6870,首次打开时,会做一些必要的配置,如私人模式还是多用户模式。admin账号和密码设置等。完成后就可以愉快的使用talebook存取电子书籍了。 对于网络下载的各种电子书文件,元信息可能都不准确,因此需要从豆瓣等刮削元信息。开源社区有一个现成的刮削服务,douban-api-rs:源码地址为:https://github.com/cxfksword/douban-api-rs,这个也提供Docker的安装方式,不过作者并没有在Dockerhub上面放镜像。而是在Github自己的镜像服务上面托管镜像。如果是命令行安装,只需要执行如下命令即可:

docker run -d \
--name=douban-api-rs \
--restart=always \
-p 172.17.0.1:8080:80
ghcr.io/cxfksword/douban-api-rs:latest

如果是群晖等NAS服务,则需要自行配置新的镜像源才能拉去到该镜像。具体笔者没有使用过,需要自行探索。 然后到Talebook的高级配置项目中配置即可:

image

我这里之所以选择使用172.17.0.1作为监听地址,是因为这个地址是我的docker服务的网络的虚拟网关,宿主机也能访问这个IP地址。这样,在Talebook内部就能用这个地址与豆瓣刮削服务通信。上传电子书之后,只要设置正确的书籍名字即可进行全量元数据的抓取了。豆瓣网站不再提供书籍的标签(Tag)了,因此Talebook服务端做了从作者、标题和书籍摘要中匹配Tag的实现,准确率还行。 感谢Talebook作者贡献这么好的开源项目,并且多年来还在积极维护。这个项目也让我初步接触到Vue.js、Node.js、Python3 Tornado等生态,开发WEB项目,使用这些组件,效率极高。什么时候有精力可以把jAlbum的前端好好用这些写一下。

| 1 分2 分3 分4 分5 分 (5.00- 3票) Loading ... Loading ... | 同时归档在:WEB网络, 建站技术, 数码硬件 | 标签: , , , , , |

Home NAS 音乐服务解决方案

之前写过使用《使用Emby + Picard管理音乐》的方案,Emby有一个问题,在划词搜索方面,必须前缀或者整词完整匹配,对于港台音乐名和元数据多是繁体字,用简体搜索时,无法匹配,一直希望能够模糊匹配,发现airsonic-advance这方面没问题,完美解决搜索问题。

阅读全文 »

| 1 分2 分3 分4 分5 分 (5.00- 1票) Loading ... Loading ... | 同时归档在:数码硬件, 软件应用 | 标签: , , , , |

自制一个动态域名解析系统

之前一直用路由器自带的动态域名解析(Dynamic DNS,DDNS)系统,一般路由器自行提供一个,或者直接对接花生壳。路由器自带的几乎不能登录,花生壳也是经常性的退出登录,或者直接把域名解析为127.0.0.2,遇到好几次了,难以忍受。仔细研究了一下百度云的域名服务,希望找到一个能够通过远程调用设置A记录的入口。找到了这个介绍链接:更新域名记录,使用百度云的域名解析服务的API可以实现对域名解析的各种远程操作。首先在《HomeNAS IP地址变化》中介绍了如何获取本机真实IP的方法,然后当监控到IP发生变化时,调用API设置A记录即可。本来想使用Python SDK简单写几行脚本直接运行起来就好,结果百度云域名服务的Python SDK以及给出的几行样例代码漏洞百出,没法实际运行起来。只能做个Java Jar包供命令行调用了。这样终于搞定了一个可以长时间稳定运行的DDNS实现,一个完美的花生壳替代品。

先列举所有主域名的解析配置,找到需要修改的那一项,然后使用列举得到的ID设置新的IP地址即可。详细代码参见如下工程:https://git.codefine.site:3000/Shentar/setdomain2

| 1 分2 分3 分4 分5 分 (5.00- 1票) Loading ... Loading ... | 同时归档在:WEB网络 | 标签: , , |

HomeNAS IP变化规律

成都电信分配给个人的家用宽带IP地址定期更新,本来是用来快速发现变化后的IP地址的一个任务,解决IP地址变化后需要15分钟才能登录的问题,结果让发现了IP地址变化的规律。每隔6天,在每天中午11点20后的一个小时内更新IP地址。不知道是只针对特定账号的任务还是所有人同一时刻变更。

阅读全文 »

| 1 分2 分3 分4 分5 分 (5.00- 1票) Loading ... Loading ... | 同时归档在:WEB网络, 实用脚本 | 标签: , , |

分享一个实时抓取IT相关博客和新闻的业务

一直通过TTRSS订阅各大IT门户和博客的文章,其实这些内容更适合公开访问,于是简单做了个页面,后台通过java程序直接访问TTRSS的数据库生成页面。内容不是全网爬取的,是定点几个比较大的门户网站的,搜索条件比较简单,通过关键词过滤内容或者标题。后台准实时拉取各个Feed的文章,然后定时半个小时刷新一次页面,半个小时内,网页呈现都是缓存的内容。因为爬取数据的过程是现成的,主要工作是做个动态页面,几个小时就搞定了。程序放在家里的NAS上面运行。

访问地址:https://news.codefine.site:12524

IT News

| 1 分2 分3 分4 分5 分 (5.00- 1票) Loading ... Loading ... | 同时归档在:WEB网络, 软件应用 | 标签: , , , , |

分享一个追最新外语电影的RSS

国内的Torrent分享网站越来越少了,无意中发现https://www.demonoid.is/可以下载到最新的高清/超清电影。但是有点比较讨厌,就是弹窗有点过份,不是我白嫖了种子还不愿支持广告,真是弹窗太过三俗刺眼,难以忍受。于是试着分析了网页内容,自己抓取电影种子文件链接,并添加Google搜索IMDB的链接,制作了RSS订阅链接。本来还想找一下有没有类似的Torrent分享站点,发现demonoid是与海盗湾齐名的,之前排名前几的站点已经都无法打开了,只剩这一个,切用且珍惜吧  :-) 源站地址:链接,经过抓取清洗和加工后生成的RSS链接为:https://photo.codefine.site:12524/rssfactory/demonoid-movies,只抓取了1080P及其以上质量的电影。 https://www.demonoid.is/

订阅后的呈现效果:

 image

同时也制作了HTML版的独立网页:

https://movie.codefine.site:12524/

movie list.

电影详情页,包含两个torrent下载地址,IMDB和豆瓣搜索链接。

movie detail.

| 1 分2 分3 分4 分5 分 (5.00- 1票) Loading ... Loading ... | 同时归档在:WEB网络, 数码硬件, 软件应用 | 标签: , , |

安装 FileRun,HomeNAS 秒变网盘

HomeNAS上面虽然可以使用SFTP、WebDAV和NAS等协议分享文件,但是在易用性上面还是不如网盘的短连接+简单密码的方式好用。一直想找一个类似网盘的HTTP短连接分享的系统。EMBY的分享按钮似乎不能正常工作,更别谈使用带密码校验的功能了。之前Windows系统的Everything,只支持单个账户登录。

集中搜索了一下类网盘的解决方案,发现NextCloud、H5AI和FileRun都有类似功能,首先安装了NextCloud,发现其只能管理新上传的文件,所有文件必须进入了NextCloud的数据库才能被管理起来,NextCloud提供了命令行工具,扫描指定目录的所有文件和目录加入到其数据库中,但是每次目录有变化都需要重新扫描,不是太友好。直接放弃。

H5AI就没有尝试,主要发现该软件多年未更新。

最后FileRun,从软件的主页上面就看到了不需要导入文件的介绍:

FIleRun

使用docker镜像安装,网上其他资料都是介绍的使用docker-compose安装的,这里我本机已经有mysql的容器在运行了,因此直接使用docker run启动FileRun容器:

docker run -d \
--name filerun \
-p 8080:80 \
-v /opt/filerun/html:/var/www/html \
-v /media:/user-files \
-e FR_DB_HOST=yourdbhostip \
-e FR_DB_PORT=3306 \
-e FR_DB_NAME=filerun \
-e FR_DB_USER=filerun \
-e FR_DB_PASS='yourdbpasswrod' \
-e APACHE_RUN_USER=www-data \
-e APACHE_RUN_USER_ID=33 \
-e APACHE_RUN_GROUP=www-data \
-e APACHE_RUN_GROUP_ID=33 \
afian/filerun

其中/media是HomeNAS希望被管理的文件的根目录。使用superuser:superuser登录后,修改默认密码,完美呈现出media目录的所有文件。所有的文件相关操作均可在FileRun的WEB客户端上面操作。也能使用链接分享文件或者目录。访问分享链接的客户能在页面上一键打包下载所有文件,也能单个下载某个文件。

image

| 1 分2 分3 分4 分5 分 (5.00- 1票) Loading ... Loading ... | 同时归档在:WEB网络 | 标签: , , , , |

使用Emby + Picard管理音乐

最近把NAS上面累积下来的音乐都整理了一下,用emby建了一个音乐集。emby自带musicbrainz的插件,能从这个强大的音乐库中搜索MP3的元数据信息。然后从多个维度对音乐进行分类呈现。但是有个问题,很多MP3经过各个二道贩子编辑后,关键元数据信息都跟音乐本身没有任何关联了,因此自动搜索出来的元数据匹配存在一些问题,甚至有的MP3文件经过转码后,只剩下音乐本身,tag元数据全部丢失。只能人工填写,一两千个文件,逐一搜索排查可想而知难度有多大。找到了picard这个工具,可以自行匹配,然后没有匹配的再人工搜索,这样极大提高了准确率。比emby自动但是做了的错误的匹配要好的多。经过picard处理后的音乐文件再导入到emby中,就能准确识别歌手,专辑等信息,进而补充下载专辑唱片封面图等。

难得的是,picard在Win、Linux和Mac平台都能使用。对于Ubuntu 20,使用官方给出的命令很快就能安装成功:

sudo add-apt-repository ppa:musicbrainz-developers/stable
sudo apt-get update
sudo apt install picard

软件界面截图:
picard

导入/emby的效果:
emby

| 1 分2 分3 分4 分5 分 (5.00- 1票) Loading ... Loading ... | 同时归档在:数码硬件, 软件应用, 软件技术 | 标签: , , , |

基于Dlib、Flask和Sqlite的人脸检测和识别服务

这个十一原定的计划取消了,没有做好备份计划,也就不打算出远门了,关在家里,把一直都想做的一个本地化的人脸识别服务整了一下。提供人脸分析的开源服务似乎很多年都没有大的变化了,一直都是Dlib和OpenCV,对比了一下,Dlib更容易使用。一直没有正经写过Python代码,翻出N年前买的Python编程书,边翻书Google、边写代码。基本的代码流程比较简单,Dlib官方也有例子,很容易运行起来,但是要服务化,要做人脸比对,并且是增量的人脸比对和识别,并不容易。说做就做,最终整个服务形成如下架构。

架构图:
image

代码和部署使用方法在如下git工程:https://git.codefine.site:3000/Shentar/facerec

首先需要将探测的过的“人脸”存储起来,然后能输入一张人脸返回与该人脸近似的所有人脸,这样客户端好做人脸归集。很快做好了一个初步的框架:使用Flask提供REST接口接收照片,在响应中返回人脸的特征标识,使用SHA256对人脸68点位的描述向量进行HASH,返回给客户端。同时将HASH值和实际的token存储到Sqlite。第一天大概就完工了这个功能。

运行起来,发现单纯的Flask不能并发,第二个请求会报错,一次只能接受和处理一个请求。于是又按照网上的经验,使用Gunicorn和Gevent来做多线程的方案,因为习惯了单进程多线程的方式,多线程访问Sqlite需要加锁,按照通用的做法,使用一个队列来管理Sqlite实例。继续验证,发现多线程并不能加速Detect的效率,貌似Dlib不支持多线程加速。调整为多进程,四个CPU都能运用起来。

1d2dd2b5bcde40b6a563996821d84843

终于找到了一个能将这个3.2GHZ的四核CPU跑满的业务了 ^_^

Architecture: x86_64
CPU op-mode(s):                  32-bit, 64-bit
Byte Order:                      Little Endian
Address sizes:                   39 bits physical, 48 bits virtual
CPU(s):                          4
On-line CPU(s) list:             0-3
Thread(s) per core:              2
Core(s) per socket:              2
Socket(s):                       1
NUMA node(s):                    1
Vendor ID:                       GenuineIntel
CPU family:                      6
Model:                           94
Model name:                      Intel(R) Core(TM) i3-6100T CPU @ 3.20GHz

人脸检测的效果还不错,错误率的话,自己家用是够了。特别是在侧脸检测上面,比较准确。在人脸比对方面,错误率就要高一些了,反复验证,发现0.36的比对阀值比较合适。侧脸虽然检测率高,但是在比对上面,只用通用的拟合范数,结果会表现为差异很大。因此这里应该是需要有定制化的比对实现,只做部分比对。这块需要深入到人脸检测技术内部,去分析128D的特征值向量的每一个值,短时间内没办法去研究透了。

由于采用了多进程,因此没法共用一个Sqlite运行时实例,强行并发读写访问会导致数据库错乱,不得不又做了一个服务来封装Sqlite,多个检测进程输出的人脸特征值都发给该服务来顺序存储,同时也返回给客户端。两个服务之间同样采用REST接口交互。

准备大规模上量,将jAlbum目前使用的线上人脸识别服务切换到这个本地服务上面,又发现检测时长非常高,一张4M的图片,大概需要几秒的时间,并且还有些非常小的区块被检测到了。对于检测慢的问题,考虑降低输入的照片的像素,图片减小后,长宽的像素点都相应减少了,但是人脸的特征点并不会损失太多。因此先对图片进行降低像素和尺寸,识别完成后,对识别到的人脸在照片上的位置也要相应做缩放,对比了一下,原始大小检测和缩放后检测,再对结果做相反的缩放,最终结果误差不大,但是这样能极大提速。对于非人脸和质量不高的人脸被检测到的问题,做了一些粗浅的限制,人脸长宽必须大于100的阀值才认为是正常的人脸。Dlib应该有正统的输出人脸的质量的参数,查了很久,没有找到合适的方法,就只能先这样吧。在比对方面,还有一些重要的概念,没有弄明白,如人脸对齐、年龄、性别检测等,不清楚我的代码里面是否已经有调用已经做了这块。

具体的处理代码:

data = np.frombuffer(data, np.uint8) 
if data is None: 
    raise Exception('image is required.') 

zoom_ratio = 1 
if data.size > 6 * 1024 * 1024: 
    img = cv2.imdecode(data, cv2.IMREAD_REDUCED_COLOR_4) 
    zoom_ratio = 4 
elif data.size > 4 * 1024 * 124: 
    img = cv2.imdecode(data, cv2.IMREAD_REDUCED_COLOR_2) 
    zoom_ratio = 2 
else: 
    img = cv2.imdecode(data, cv2.IMREAD_COLOR) 

faces = [] 
dets = detector(img, 1)

总的来说,开源项目,适合做一下Demo,如果要尽善尽美,那么就要深入到源码,有针对性的去优化检测和比对模型。作为个人的实验和家用还是很不错的。至少在快速编程和服务化这方面。

| 1 分2 分3 分4 分5 分 (5.00- 2票) Loading ... Loading ... | 同时归档在:WEB网络, 数码硬件, 架构设计, 软件应用 | 标签: , , , , , |
返回顶部