之前弄了个同步盘,用的NextCloud,结果出了点啥问题连个日志都没有,根本查不到报的什么错,一气之下就卸了,什么辣鸡玩意儿,之后换了国产Seafile,用着还行,起码出了问题我能看到日志了。
用了一阵子偶然发现他这个文档不能在线协作编辑,查了下文档,可以用Onlyoffice对接实现,弄出来效果还挺不错的,不光能协作,还能聊天,欢迎来到Excel聊天室(不是。
期间踩了点坑,国内基本没有相关资料,因为像我这种闲得蛋疼在k8s里搭建seafile+k8s+onlyoffice并且使用traefik作为ingress实现的实在是太少了,虽然这个经验很有针对性,但是还是想记录下来,万一有人跟我遇到了一样的问题,可以少浪费点时间。
K8S部署Seafile
官方只提供了docker-compose.yml文件,我照葫芦画瓢整了个yaml,比较精简,但够用:
apiVersion: apps/v1
kind: Deployment
metadata:
name: seafile
namespace: default
labels:
app: seafile
spec:
replicas: 1
selector:
matchLabels:
app: seafile
template:
metadata:
labels:
app: seafile
spec:
volumes:
- name: seafile
persistentVolumeClaim:
claimName: seafile-pvc
containers:
- name: seafile
image: 'seafileltd/seafile-mc:latest'
ports:
- name: http
containerPort: 80
protocol: TCP
env:
- name: DB_HOST
value: 10.1.245.189
- name: DB_ROOT_PASSWD
valueFrom:
secretKeyRef:
name: mysql-pass
key: password
- name: TIME_ZONE
value: Asia/Shanghai
- name: SEAFILE_ADMIN_EMAIL
value: 569812422@qq.com
- name: SEAFILE_ADMIN_PASSWORD
value: 123456
- name: SEAFILE_SERVER_LETSENCRYPT
value: 'false'
- name: SEAFILE_SERVER_HOSTNAME
value: cloud.hafuhafu.cn
resources: {}
volumeMounts:
- name: seafile
mountPath: /shared
terminationMessagePath: /dev/termination-log
terminationMessagePolicy: File
imagePullPolicy: IfNotPresent
restartPolicy: Always
没啥好说的,就规规矩矩的一个资源文件,env方面去seafile官网的服务器手册对照下就行了,但按我提供的这个应该也够了,注意数据库你需要自己部署,如果你用的不是mysql,你可以去官网看看支持啥其他数据库。
service和ingress我这省略了,如果你不会写service和ingress,可以去看一下我之前的k8s资源介绍方面的文章。
服务启动完成后,将以下内容添加到/var/opt/seafile/conf/seahub_settings.py以开启Onlyoffice,注意URL是外网可访问的地址,比如域名、NodePort或HostPort:
# Enable Only Office
ENABLE_ONLYOFFICE = True
VERIFY_ONLYOFFICE_CERTIFICATE = False
ONLYOFFICE_APIJS_URL = 'http{s}://{your OnlyOffice server's domain or IP}/web-apps/apps/api/documents/api.js'
ONLYOFFICE_FILE_EXTENSION = ('doc', 'docx', 'ppt', 'pptx', 'xls', 'xlsx', 'odt', 'fodt', 'odp', 'fodp', 'ods', 'fods')
ONLYOFFICE_EDIT_FILE_EXTENSION = ('docx', 'pptx', 'xlsx')
部署Onlyoffice
Onlyoffice是一个开源协作office编辑器,我对这个东西的了解也有限,不展开介绍,直接上Yaml:
apiVersion: apps/v1
kind: Deployment
metadata:
name: only-office
namespace: default
labels:
app: only-office
spec:
replicas: 1
selector:
matchLabels:
app: only-office
template:
metadata:
labels:
app: only-office
spec:
volumes:
- name: only-office
persistentVolumeClaim:
claimName: only-office-pvc
containers:
- name: only-office
image: onlyoffice/documentserver
ports:
- name: http
containerPort: 80
protocol: TCP
env:
- name: DB_TYPE
value: mysql
- name: DB_HOST
value: mysql
- name: DB_PORT
value: '3306'
- name: DB_NAME
value: onlyoffice
- name: DB_USER
value: root
- name: DB_PWD
valueFrom:
secretKeyRef:
name: mysql-pass
key: password
volumeMounts:
- name: only-office
mountPath: /var/log/onlyoffice
subPath: log
- name: only-office
mountPath: /var/www/onlyoffice/Data
subPath: data
- name: only-office
mountPath: /var/lib/onlyoffice
subPath: onlyoffice
- name: only-office
mountPath: /var/lib/rabbitmq
subPath: rabbitmq
- name: only-office
mountPath: /var/lib/redis
subPath: redis
- name: only-office
mountPath: /etc/onlyoffice/documentserver/local.json
subPath: config/local.json
imagePullPolicy: IfNotPresent
restartPolicy: Always
这里注意下挂载的local.json文件,里面有一些要修改的配置项,需要在该文件内加入以下内容,以开启文档自动保存功能:
{
"services": {
"CoAuthoring": {
"autoAssembly": {
"enable": true,
"interval": "1m"
}
}
}
}
部署好之后配置一下service和ingress就行了,地址要和seafile的setting中填的一样,好了之后访问一下可以看到onlyoffice的欢迎界面,接下来就可以看看seafile里的office是否能正常打开,你可以看到一个新的编辑页面了。
如果你是用的Nginx的ingress实现,那接下来的就跟你没关系了。
Traefik作为Ingress时,wss和http[s]不同造成跨域
Traefik2.0就是太严谨了,https同域名发起websocket访问都会被CORS给干掉,Nginx就没有这个问题,导致可查阅的资料那是相当的少,不过我搞了一天还是找到方案了,原文在这里,我这里截一下最重要的部分:

他这里提供了docker-compose的解决方案,我照着这个方案搞了个k8s的版本,首先这个方案要使用traefik的自定义资源,我们用这个来创建一个中间件,Middleware:
apiVersion: traefik.containo.us/v1alpha1
kind: Middleware
metadata:
name: onlyoffice-cors
namespace: default
spec:
headers:
accessControlAllowOriginList:
- 'wss://office.hafuhafu.cn' # 指定你onlyoffice的域名地址,用wws协议
customRequestHeaders:
X-Forwarded-Proto: https # 标注自定义请求头
之后创建ingress或traefik的ingressRoute,根据你喜好任选其一:
# ingress
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: only-office
namespace: default
labels:
app: only-office
annotations:
traefik.ingress.kubernetes.io/router.entrypoints: 'web,websecure' # 根据你自己的traefik配置来
traefik.ingress.kubernetes.io/router.middlewares: default-onlyoffice-cors@kubernetescrd # 这里是完全限定名 <中间件namespace>-<中间件name>@kubernetescrd
spec:
ingressClassName: traefik
rules:
- host: office.hafuhafu.cn
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: only-office
port:
number: 80
# ingressRoute
apiVersion: traefik.containo.us/v1alpha1
kind: IngressRoute
metadata:
name: onlyoffice
namespace: default
spec:
entryPoints:
- web
- websecure
routes:
- kind: Rule
match: Host(`office.hafuhafu.cn`)
middlewares:
- name: onlyoffice-cors
services:
- name: only-office
port: 80
实际上就是通过中间件给wss的域名访问开了下白名单,属于是隐藏错误的方式,目前onlyoffice官方还没有给出traefik2.0+的解决方案。
至此,私人协作云文档就搭建完了,如果你没有自己的k8s集群,那么也可以使用docker和文中的镜像来搭建一个一样的,最后打开你的seafile,创建一个文档来看看是不是可以正常打开且编辑就可以了,如果发现和你协作编辑的人没有编辑权限,注意查看seafile的共享资料库是不是被设置为其他人仅可读了,反正onlyoffice的权限已经对接到seafile了,如果有任何权限问题八成是seafile没配置好。