当前开发环境与外网是隔绝的,团队又是一个不足10人的小团队,然而互相传送各种修改的word,excel经常造成版本不对,或者内容缺失。所以很需要一个类似石墨文档或者飞书的在线文档服务,只要能满足多人在线编辑,导入与导出,关键是要能局域网部署(私有化部署),需要的时候只需一键启动,显然尽量要用docker ,免去各种繁琐的配置。公司只有confluence,显然也不准备搞个这样的服务,团队也没有金钱去购买企业级应用,所以理所当然找个开源产品。
搜索了一下,发现并不好找。虽然现在这种在线文档挺火,但开源的并且能够本地部署的框架去并不多,很多企业都在搞在线文档,要么需要联外网要么不支持本地部署。开源产品中Luchysheet,x-sheet只能处理excel文件;poi-tl, DOC4J只能处理word;kkFileView只能在线预览文件,不能编辑;而只有onlyoffice,支持多种格式文件的预览和编辑,并且还区分用户操作权限,另外最重要的一点是支持本地部署,还免费。所以准备尝试运行一下。
另外还有国产开源的JVS,但我上手体验了一下,有2个缺点:
-
镜像没有考虑arm64架构,特别是它的
jvs-rabbitmq:management
似乎是定制的rabbitmq,本地根本运行不起来,不停的报错:standard_init_linux.go:207: exec user process caused "exec format error"
,这是典型的系统架构不兼容错误。 -
庞大臃肿消耗资源,仅仅是运行镜像集群中的数据库部分,我的机器就已经完全卡顿;虽然JVS官方明确推荐使用16G内存的机器,但是同样是我的8G机器,运行onlyoffice则一点问题没有。
预备知识
文档服务器
onlyoffice提供商业版和社区版。开源的社区版只提供文档服务器服务,这个所谓的文档服务器(DocumentServer)是一坨js和css,需要集成进外部的服务中;或者说在线文档的编辑查看存储功能本身是完备的,但还需要了解它的各种接口和功能进行二次开发;并不是像石墨和飞书那样有用户登录系统,还有直观的文件存储位置。这是首先要了解的,我最开始也想当然的认为用户登录与文件存储都是一体的,结果运行起来后发现什么也干不了,所以一度放弃onlyoffice,转而尝试JVS,后来看到onlyoffice示例程序才明白过来。
镜像架构
为了避免繁琐的配置以及影响当前机器的正常使用,显然我们最好用docker镜像,然而镜像其实也是区分硬件的。有的镜像需要在指定的平台机器上才能正确运行,docker镜像并不是平台无关的。然而好多的在线文档开源框架都是默认使用amd64的,拉取的镜像也是针对这个架构的,而我的机器偏偏是一台arm64的笔记本,结果按照文档操作费劲巴拉地下载了巨大的镜像后根本运行不起来。要是预先知道这些前提知识,就可以节省很大的时间与精力。
拉取镜像
工具安装
首先,docker的工具必须先安装好,这个无须多言。然而就算docker工具安装好,也可能遇到其它的坑。比如在另外一台x86_64的机器上,明明按照官方说明文档README运行镜像,可还是无法运行;我甚至一度自己制作镜像,结果又遇到另外一坨其它问题,太难受了。另外docker的镜像加速也一定要配置好,否则后面拉取镜像会非常慢,让人抓狂。这个配置操作网上信息很多,不再叙述。
为了达到复用的目的,单一功能的镜像一般都拆出来再单独制作成镜像,如mysql, redis, 多个镜像协同工作,构成镜像集群。onlyoffice也用到了镜像集群,所以就需要用到docker-compose
了。管理多个镜像的工具docker-compose
,也是区分本地机器架构的,一定要找到正确的下载地址或安装方式。
镜像配置
然后git clone https://github.com/ONLYOFFICE/Docker-DocumentServer.git
,当前commit点:558353ee99f
。这个仓库包含了镜像运行的配置文件,当然还有制作镜像的配置,制作镜像这部分我们不涉及。如果是x86_64或者amd64的机器可以直接运行:docker-compose -f docker-compose.yml up -d
。然而这个操作在官方文档README里竟然没有,如果对docker-compose
一无所知,徒手运行docker命令,很容易出问题;因为DocumentServer运行明明是需要其它镜像的协同的。如果是arm64的机器要做如下更改:
diff --git a/docker-compose.yml b/docker-compose.yml
index 51fafb2..7c3f47b 100644
--- a/docker-compose.yml
+++ b/docker-compose.yml
@@ -1,8 +1,7 @@
version: '2'
services:
onlyoffice-documentserver:
- build:
- context: .
+ image: onlyoffice/documentserver:latest-arm64
container_name: onlyoffice-documentserver
depends_on:
- onlyoffice-postgresql
@@ -34,14 +33,14 @@ services:
onlyoffice-rabbitmq:
container_name: onlyoffice-rabbitmq
- image: rabbitmq
+ image: arm64v8/rabbitmq
restart: always
expose:
- '5672'
onlyoffice-postgresql:
container_name: onlyoffice-postgresql
- image: postgres:9.5
+ image: arm64v8/postgres:10.22-alpine
environment:
- POSTGRES_DB=onlyoffice
- POSTGRES_USER=onlyoffice
可以从配置文件看出需要rabbitmq
和postgres
,更换成对应架构的镜像。arm64架构的postgres
只有10.0以上的版本,这里也可能有风险,因为版本一改,谁知道哪里会出岔子。然后就是把制作镜像的操作换成直接拉取(注意是arm64架构的)。再运行docker-compose -f docker-compose.yml up -d
命令。
如果顺利的话,当这个操作结束完,就能看到onlyoffice/documentserver
实例运行,通过docker container ps
查看:
094f46c53d09 onlyoffice/documentserver:latest-arm64 "/app/ds/run-documen…" 0.0.0.0:80->80/tcp, 0.0.0.0:443->443/tcp onlyoffice-documentserver
浏览器打开http://0.0.0.0
应该能看到onlyoffice的欢迎页:
运行内置示例
欢迎页中会直接提醒用户运行容器内的一个命令,这个命令其实就是启动一个网页服务来验证是否正确执行,并让用户熟悉和了解操作和交互的:
docker exec 094f46c53d09 sudo supervisorctl start ds:example
再点击欢迎页上的按钮,跳转到地址http://0.0.0.0/example
:
这里就可以展示如何上传下载,打开编辑各种word,excel了。
这里又有一个坑:把docker-compose.yml
配置文件中onlyoffice-documentserver
的端口映射改成9000
后:
@@ -20,7 +19,7 @@ services:
#- JWT_HEADER=Authorization
#- JWT_IN_BODY=true
ports:
- - '80:80'
+ - '9000:80'
- '443:443'
stdin_open: true
restart: always
再运行docker-compose命令重启所有服务,示例程序竟然运行错误,总是提醒我无法保存,还不知道是怎么一回事。
运行集成示例
内置的应用基本啥也做不了,需要再做二次开发才可以集成到自己的应用中。这种开发形式对初用者不是很友好,不过官方还是比较贴心地提供了各种开发语言实现的用于集成的示例程序,需要单独下载,让开发者明白个中规则。习惯于一体化的人,比如我,一开始摸不关头脑,不知道要到底要如何操作才能像石墨和飞书那样。原来是需要集成。对Springboot和javaee熟悉的人也能立刻明白需要做什么了,偏偏我对这二个都非常不了解。
Spring示例
Spring集成示例通过这个链接下载。Spring框架能直接启动一个本地服务器来查看效果,应当是最方便的。即使对Spring不熟悉也不要紧,运行之后可以直接看服务器效果。对maven构建配置熟悉的人已经明白怎么回事了,只要按照官方文档上的描述,修改本地配置文件就可以自如运行了:
-server.port=4000
+server.port=9000
-files.docservice.url.site=http://documentserver/
+files.docservice.url.site=http://0.0.0.0/
但对只熟悉gradle的人来说有点麻烦,需要另外下载和了解maven命令,通过本地的gradle命令可以轻松把maven工程转成gradle工程:gradle init
,根据命令行提示生成相应build.gradle
文件。然而这个默认转化操作是不完备的!直接运行会因为各种Model对象没有getter和setter而报错,需要再在build.gradle文件中添加:
@@ -5,13 +5,12 @@
plugins {
id 'java'
id 'maven-publish'
+ id 'org.springframework.boot' version '2.7.3'
}
repositories {
mavenLocal()
- maven {
- url = uri('https://repo.maven.apache.org/maven2/')
- }
+ maven { url 'https://maven.aliyun.com/repository/public' }
}
dependencies {
@@ -26,6 +25,7 @@ dependencies {
implementation 'org.modelmapper:modelmapper:2.4.2'
runtimeOnly 'com.h2database:h2:1.4.200'
compileOnly 'org.projectlombok:lombok:1.18.20'
+ annotationProcessor 'org.projectlombok:lombok:1.18.20'
}
group = 'com.onlyoffice'
因为对spring不了解,花了老半天,才发现报错原因是需要加spring的插件和注释处理器。
再运行./gradlew bootRun
就可以直接运行示例网页程序了。
Java示例
java集成示例通过这个链接下载。纯粹java项目的麻烦之处是需要单独运行一个tomcat服务器,需要开发人员预先知道怎么放置生成后的war包,否则不知道如何运行。同样先按文档描述修改本地项目的配置文件。同样也可以用gradle命令把maven项目转成gradle项目,但是生成的build.gradle
也需要改一下:
diff --git a/build.gradle b/build.gradle
index bf859d8..851b2a0 100644
--- a/build.gradle
+++ b/build.gradle
@@ -5,13 +5,12 @@
plugins {
id 'java'
id 'maven-publish'
+ id 'war'
}
repositories {
mavenLocal()
- maven {
- url = uri('https://repo.maven.apache.org/maven2/')
- }
+ maven { url 'https://maven.aliyun.com/repository/public' }
}
dependencies {
运行./gradlew war
生成.war文件:build/libs/OnlineEditorsExampleJava-1.0.war
。
最关键的是让tomcat服务器把.war文件运行起来。当然最好还是继续使用容器,可官方文档里没用对这部分需要的镜像安装进行描述,而偏偏我对tomcat也是一无所知,而真是让人头大。通过一番搜索,才给整明白了:
- 拉取tomcat镜像:
docker pull arm64v8/tomcat:8.5-jdk8-openjdk-slim
,注意是arm架构的。 - 运行镜像
docker run -it --rm -p 9999:8080 -v /home/wesley/Work/projects/onlyoffice/java-example/build/libs:/usr/local/tomcat/webapps arm64v8/tomcat:8.5-jdk8-openjdk-slim
。也就是说war包生成的目录映射成tomcat中网页服务器目录/usr/local/tomcat/webapps
- 这样就可以在浏览器中打开
http://0.0.0.0:9999/OnlineEditorsExampleJava-1.0
来查看示例网页程序了。
集成示例与内置示例一模一样,不过到此为止,开发者应该知道后续要怎么做了。
通过这两个示例看java代码写成的网页服务器,的确给人一种臃肿繁琐的感觉,官方应该再出一个kotlin语言的示例程序。
13:09-16:16