一、背景概述

本手册旨在为读者提供 PlayEdu 商业版系统安装和运维指导。本手册提供的安装方式主要是基于Docker的形式进行安装,为读者提供了docker-compose一键拉起服务运行方式。同时也提供了站点https的配置教程。另外,也提供了在使用playedu过程中所需要依赖的第三方服务的配置教程,如:阿里云OSS,腾讯云COS,钉钉,飞书,企业微信等等的集成。考虑到随着程序的持续迭代,升级过程必不可少,因此我们也提供了playedu升级的教程。下面将附一张playedu的应用架构图,以便于您快速了解playedu的整体应用架构。

二、安装系统

2.1 服务器要求


最低配置推荐配置
CPU2h8h
内存4G16G
硬盘40GB200GB
带宽5M50M

2.2 操作系统

下面操作系统均支持

2.3 Docker版本要求

可执行 sudo docker version 查看:
Client:
 Cloud integration: v1.0.35+desktop.5
 Version:           24.0.6
 API version:       1.43
 Go version:        go1.20.7
 Git commit:        ed223bc
 Built:             Mon Sep  4 12:28:49 2023
 OS/Arch:           darwin/arm64
 Context:           desktop-linux
笔者编写本文所使用的 Docker版本是24.0.6,请确保您所使用的版本大于等于这个版本号。

2.4 开始安装

2.4.1 docker-compose安装程序

下文假设您已经完成了playedu交付程序的解压,并进入到了解压后的程序目录。

2.4.1.1 创建配置文件

首先,我们需要创建个.env的配置文件,此文件在镜像构建和容器运行的时候均需要用到。执行下面命令创建:
cp .env.example .env

2.4.1.2 构建docker镜像

接下来,请运行下面命令完成playedu的镜像的构建工作:
# 构建playedu镜像
docker compose build playedu

# 构建转码服务镜像
docker compose build document

2.4.1.3 运行服务

镜像构建完成之后,通过下面命令拉起服务:
📢 我们分两个命令拉起playedu服务。对熟悉compose的小伙伴可能就说了,可以在compose.yml中设置depends 依赖,直接通过 docker compose up -d playedu 就可以了,这样更简洁。 这的确没有错,但是考虑到我们交付给客户,客户可能并不是所有的服务都通过compose运行,比如:mysql,redis,kafka这一类中间件可能独立安装,这种场景下就不能依靠depends限制playedu的运行依赖容器了。有关于服务拆分运行,我们将会在后文说到。

📢 如果您不想将mysql,redis,kafka中间件通过docker容器方式运行话,您可以修改.env中的mysql,redis,kafka的配置。然后在docker compose up的时候删除对应中间件的名称即可。

⚠️请注意⚠️:如果您计划使用阿里云OSS或腾讯云COS托管视频文档等资源的话,那么您可以忽略minio服务的创建运行。也就是移除下方docker compose up -d命令后的minio
# 拉起mysql,redis,kafka,minio依赖服务
docker compose up -d mysql redis minio kafka

# 拉起 playedu 服务
docker compose up -d playedu

# 拉起转码服务
docker compose up -d document

2.4.1.4 访问服务

命令执行完成,等到20s左右,我们就可以在浏览器输入下面的地址访问playedu的服务:
请注意,容器构建的过程我们将用户界面三个静态站点文件和playedu api程序封装在一个容器里面。
端口地址账号/密码
后台管理http://localhost:9900admin@playedu.xyz playedu
PChttp://localhost:9800-
H5http://localhost:9801-
APIhttp://localhost:9700-
MinIO服务端http://localhost:9002-
通过上述链接简单体验了playedu的功能之后,我们还需继续安装。

2.4.1.5 配置域名访问

接下来是将9700,9800,9801,9900,9002五个端口更换为通过80443端口访问。
因为5个端口走的都是80443端口,因此我们需要通过域名来确定访问的是哪个端口,下面是我的域名分配方案仅供读者参考。需要注意的是,您完全可以按照自己的想法和要求分配域名方案,但是不管如何定义域名,五个子域名数量是必不可少(这里需要注意的是:如果您精通nginx且通过子目录的方式而不是域名的访问分配站点访问服务的话也是可以的):
⚠️请注意⚠️:如果您计划使用阿里云OSS或腾讯云COS托管视频文档等资源的话,那么您可以忽略minio服务域名的配置和下文中的minio服务的SSL证书配置。
业务端口端口域名分配
后台管理9900admin.playedu.xyz
PC9800edu.playedu.xyz
H59801h5.playedu.xyz
API9700api.playedu.xyz
MinIO服务端9002minio.playedu.xyz
域名分配好了之后,因为我们也需要通过443端口访问,因此我们还需要准备好域名的SSL证书。准备好ssl证书之后:
这里推荐使用通配符SSL证书,通配符SSL证书的优点就是一份证书就可以作用于上述5个域名。
到这里,域名和SSL证书准备完毕,接下来,我们打开.env配置文件,按照下图配置填充下构建镜像时的参数配置:
保存.env配置,然后执行下面命令重新构建镜像:
docker compose build playedu
构建镜像成功之后,执行下面命令重新拉起playedu服务:
# 先销毁已经存在的playedu容器
docker compose down playedu

# 重新拉起playedu服务
docker compose up -d playedu
上述命令执行完成,等待20s左右,我们就可以通过域名+https协议访问各个服务端口了,快体验下吧。体验完成之后,我们将继续playedu的安装。

2.4.1.6 系统配置

我们进入到后台,打开系统配置,填写下图三个配置:
然后依旧是系统配置页面,选择S3存储配置:
到这里,playedu系统的配置基本完成,然后基本上可以在生产环境中使用了。接下来,我们还要继续配置文档转码。

2.4.1.7 文档转码服务配置

上述的容器构建过程其实已经构建好了文档转码程序的镜像并且运行了转码服务容器。命令如下:

三、系统配置

3.1 S3存储配置

3.1.1 阿里云OSS配置

阿里云对象存储 OSS(Object Storage Service)是一款海量、安全、低成本、高可靠的云存储服务,提供最高可达 99.995 % 的服务可用性。多种存储类型供选择,全面优化存储成本。

点击右侧开通阿里云oss:https://www.aliyun.com/product/oss

阿里云oss控制台:https://oss.console.aliyun.com/bucket

3.1.1.1 创建Bucket

创建Bucket - 进入到阿里云OSS控制台
点击创建bucket,在弹出的窗口完善信息:
上述表单中的第一个数值Bucket名称后续配置将会用到。

3.1.1.2 获取基础配置

获取endpointregion
创建好Bucket之后,进入到Bucket的概览页面,如下:
从上图可知
endpoint 为: https://oss-cn-hangzhou.aliyuncs.com
regioncn-hangzhou

3.1.1.3 跨域配置

🙋‍♂️ Q:为什么需要配置跨域? 💬 A:视频上传是直接在浏览器直传到OSS的,因为后台访问域名和OSSendpoint不一致,也就产生了跨域访问的问题。

3.1.1.4 获取AccessKeyIdAccessKeySecret

阿里云RAM控制台:https://ram.console.aliyun.com/users 进入到RAM控制台,点击创建用户
⚠️请注意⚠️:保存上图的 AccessKeyIdAccessKeySecret 后文需要用到。
接下来,完成授权的操作:

3.1.1.5 PlayEdu存储配置更新

将上述过程中产生的配置值配置到系统中。进入到playedu的后台管理界面,点击左侧菜单的系统配置,然后选择S3存储配置

3.1.1.6 转码服务存储配置更新

进入到playedu程序的根目录,打开.env文件,修改下面这些配置
配置修改了之后,执行下面命令使得配置生效:
# 销毁已有的转码服务容器
sudo docker compose down document

# 创建新的转码服务容器
sudo docker compose up -d document

# 启动转码进程
sudo supervisorctl restart all

3.1.1.7阿里云OSS套餐包购买

提前购买套餐包可以以更低的价格(相较于按量收费,使用多少扣多少账户余额)使用OSS。
套餐包购买链接:https://common-buy.aliyun.com/?commodityCode=ossbag&request={"region"%3A"china-common"}#/buy
需要购买下面几种套餐包

3.1.1.8 给Bucket绑定自定义域名

如果您不想使用阿里云OSS提供的Endpoint的话,那么您可以自定义一个域名,请看下面教程。
进入到阿里云OSS的控制台,点击已创建的Bucket进入,如下图:
如果域名不是阿里云注册的话,那么需要手动配置CNAME解析,如下图:
完成CNAME解析之后,我们还需要给绑定的自定义域名开启HTTPS证书,如下:
自定义域名绑定成功之后,我们还需要进入到playedu后台修改下存储的endpoint配置,如下图:
其次,我们还需要修改转码服务的存储配置,进入到playedu程序的主目录,打开.env文件,修改下面配置:
配置完成之后,通过下面命令使得配置生效:
# 销毁已有的转码服务容器
sudo docker compose down document

# 创建新的转码服务容器
sudo docker compose up -d document

# 启动转码进程
sudo supervisorctl restart all

3.1.1.9 开启CDN加速

如果您的学习群体主要集中一个城市的话比如:杭州的话,那么您可以不用考虑CDN加速的事情。但是如果您的学员横跨数个省份的话,那么就有必要开启CDN加速了。这是为什么呢?因为CDN加速可以让整个大陆的学员都可以享受极快的视频下载速度,如果直接通过OSSendpoint访问的话,其下载速度受限于所属地域的限制和用户宽带的限制(一般情况下资源的访问速度可以参考:电信宽带>移动宽带>联通宽带)。所以,为了让处于任何省份的学员都可以享受快速的视频播放体验和稳定性,CDN加速必不可少。
下面我将指导您给阿里云OSS配置CDN加速。
进入到阿里云CDN控制台(地址:https://cdn.console.aliyun.com/domain/list),点击添加域名:

CDN加速域名启用HTTPS
进入到添加的CDN域名配置管理页面:

回源授权配置
因为前面我们创建OSSBucket是私有的,也就意味着如果访问私有存储桶的任何资源都是需要签名的,因此CDN是否无法直接访问私有桶数据,所以,我们需要配置下回源授权,允许CDN访问私有桶的数据。

访问控制配置
此项配置主要用于限定通过CDN加速访问资源必须提前签名。
⚠️警告⚠️:上图中的鉴权类型必须选择C方式!!!

回到playedu的系统配置配置下CDN的配置,如下图:
开启阿里云OSSCDN加速之后,还需要额外购买一些套餐包,如下:

3.1.2 腾讯云COS配置

对象存储(Cloud Object Storage,COS)是由腾讯云推出的无目录层次结构、无数据格式限制,可容纳海量数据且支持 HTTP/HTTPS 协议访问的分布式存储服务。腾讯云 COS 的存储桶空间无容量上限,无需分区管理,适用于 CDN 数据分发、数据万象处理或大数据计算与分析的数据湖等多种场景。

开通腾讯云 COS 地址:https://cloud.tencent.com/product/cos

腾讯云COS控制台地址:https://console.cloud.tencent.com/cos/bucket

3.1.2.1创建Bucket

进入控制台,点击创建存储桶

3.1.2.2 获取基础配置

获取Bucket,region,endpoint配置,如下图:
上图中的 endpoint 的配置为 https://playedu-1306441972.cos.ap-nanjing.myqcloud.com ,这个地址并不是 playedu 需要的地址,需要将其中的 playedu-1306441972 给去掉(也就是 bucket 的值),最终 playedu 需要的 endpoint 的值为 https://cos.ap-nanjing.myqcloud.com

3.1.2.3跨域配置


3.1.2.4获取SecretIdSecretKey

浏览器打开腾讯云的访问控制台,地址:https://console.cloud.tencent.com/cam
这里的 secretIdsecretKey 后文需要用到,请妥善保存。

3.1.2.5 PlayEdu存储配置更新


3.1.2.6 转码服务存储配置更新

进入到playedu程序的根目录,打开.env文件,修改下面这些配置,如下图:
配置修改了之后,执行下面命令使得配置生效:
# 销毁已有的转码服务容器
sudo docker compose down document

# 创建新的转码服务容器
sudo docker compose up -d document

# 启动转码进程
sudo supervisorctl restart all

3.1.2.7 腾讯云COS套餐包购买

提前购买套餐包可以以更低的价格(相较于按量收费,使用多少扣多少账户余额)使用OSS。
套餐包购买地址:https://buy.cloud.tencent.com/cos
需要购买下面这些套餐包:
如下图:
具体买多少没有限制,用多少买多少。初次的话可以买少点,等用个几天估摸着每天平均用量再一次购买未来半年或者一年的用量。

3.1.2.8 给Bucket绑定自定义域名

如果您不想使用腾讯云COS默认的endpoint的话,您可以自定给COSbucket绑定个自定义域名。下面将指导您绑定自定义域名。
进入到腾讯云COS的存储桶列表(地址:https://console.cloud.tencent.com/cos/bucket),找到所需要的Bucket进入其中,点击自定义源站域名,点击添加域名,如下图:
上述操作完成之后,我们回到playedu后台系统配置-S3存储配置,修改endpoint为最新的域名,如下图:
同样,转码服务的endpoint也需要修改,如下图:
配置完成之后,通过下面命令使得配置生效:
# 销毁已有的转码服务容器
sudo docker compose down document

# 创建新的转码服务容器
sudo docker compose up -d document

# 启动转码进程
sudo supervisorctl restart all

3.1.2.9 开启CDN加速

如果您的学习群体主要集中一个城市的话比如:杭州的话,那么您可以不用考虑CDN加速的事情。但是如果您的学员横跨数个省份的话,那么就有必要开启CDN加速了。这是为什么呢?因为CDN加速可以让整个大陆的学员都可以享受极快的视频下载速度,如果直接通过OSSendpoint访问的话,其下载速度受限于所属地域的限制和用户宽带的限制(一般情况下资源的访问速度可以参考:电信宽带>移动宽带>联通宽带)。所以,为了让处于任何省份的学员都可以享受快速的视频播放体验和稳定性,CDN加速必不可少。
下面我将指导您给腾讯云的COS配置CDN加速。
进入到腾讯云COS控制台,找到已创建的

CDN域名配置HTTPS

CDN域名访问控制配置
这里的 鉴权密钥(主) 就是后面我们需要的 cdn-key

将上述过程中的配置值配置到playedu系统设置-S3存储,如下图:


3.2 通讯录集成

3.2.1 集成钉钉

钉钉是主流的办公软件之一,有成百数千万家企业正在使用钉钉。从 PlayEdu 1.5 版本开始,已经支持集成钉钉。实现一键同步钉钉通讯录,钉钉账号扫码登录、钉钉内静默授权登录、通过钉钉发送督学通知等。

创建自建应用
浏览器打开网址:https://open-dev.dingtalk.com/fe/app#/corp/app
⚠️请注意⚠️:上述网址需要先进行钉钉管理员的账号登录。

网址配置

获取应用配置值

应用权限配置
必要权限列表





通讯录个人信息读权限

调用SNS API时需要具备的基本权限

以用户的个人身份创建或更新个人待办数据

Contact.User.Read

snsapi_base

Todo.PersonalTodo.Write


待办应用中待办读权限

Todo.Todo.Read

待办任务


待办应用中待办写权限

Todo.Todo.Write

获取凭证

获取钉钉开放接口用户访问凭证的基础权限

open_app_api_base

身份验证

企业微应用后台免登接口的访问权限

qyapi_get_omp_sso_userinfo


通讯录组织基础信息读权限

Contact.Org.Read


通讯录部门成员读权限

qyapi_get_department_member


根据手机号获取成员基本信息权限

qyapi_get_member_by_mobile


成员信息读权限

qyapi_get_member


通讯录部门信息读权限

qyapi_get_department_list


邮箱等个人信息

fieldEmail

个人权限

个人手机号信息

Contact.User.mobile

通讯录管理

企业员工手机号信息

fieldMobile

安全配置

授权登录

3.2.2 集成企业微信

自建应用。登录到企业微信的控制台,地址:https://work.weixin.qq.com/wework_admin/frame

获取自建应用配置值
这里的 AgentId 和 Secret 是我们需要的信息。

设置应用主页

获取企业ID

将上述配置值配置到playedu系统中

H5(手机端口)授权域名配置

PC(电脑)端口的企业微信扫码登录域名白名单配置

企业可信IP配置

从企业微信中访问自建应用

3.2.3 集成飞书

飞书,先进企业协作与管理平台——集即时沟通、日历、音视频会议、云文档、云盘、工作台等功能于一体,成就组织和个人,更高效、更愉悦。在大陆,成千上百万的企业客户正在使用着飞书,考虑到这部分客户,我们在 PlayEdu 中实现了飞书OA系统的集成。实现了一键同步通讯录、飞书免登录、督学消息通知等。

自建应用
浏览器打开网址:https://open.feishu.cn/app
⚠️请注意⚠️:打开这个网址接下来的操作需要您先登录飞书管理员账号的。

获取配置

自建应用权限配置
需要开通的权限如下:
权限代码
更新通讯录contact:contact
获取通讯录基本信息contact:contact.base:readonly
以应用身份读取通讯录contact:contact:readonly_as_app
更新部门 IDcontact:contact:update_department_id
更新用户 IDcontact:contact:update_user_id
获取部门基础信息contact:department.base:readonly
查询部门 HRBP 信息contact:department.hrbp:readonly
获取通讯录部门组织架构信息contact:department.organize:readonly
查看、创建、修改、删除角色及角色成员contact:functional_role
查询角色信息、角色下的成员信息contact:functional_role:readonly
获取用户 user IDcontact:user.employee_id:readonly
获取与发送单聊、群组消息im:message
以应用的身份发消息im:message:send_as_bot
给一个或多个部门的成员批量发消息im:message:send_multi_depts
给多个用户批量发消息im:message:send_multi_users
获取企业信息tenant:tenant:readonly

应用安全配置

3.2.4 LDAP集成

我们根据playedu系统后台的LDAP配置项进行讲解并配置:

服务地址
服务地址的一般格式是 ldap://服务器IP:389 ,举个例子如:ldap://127.0.0.1:389 。需要注意以下几点:

用户名/密码
Window AD 域的客户可以直接填写邮箱,如下截图:
密码就是账户的密码了。

基本DN
举个例子:ou=baishu,dc=playedu,dc=xyz
从示例值举例说明: dc=playedu,dc=xyz 是基域, ou=baishu 是组织名为 baishu 的组织。示例配置的值就是限制 ou=baishu 的学员可以登录。
如果你想要让全部用户都可以登录学习,可以去掉 ou=baishu 的配置只填写基域 dc=playedu,dc=xyz

搜索范围
搜索范围也就是限制通讯录自动同步可以同步的组织范围。下面举个例子,如果你的基域下存在多个OU的话,比如有:OU=上海,OU=浙江,OU=广东如果您只想要同步上海浙江下的学员的话,那么搜索范围就可以配置为:OU=上海<and>OU=浙江

排除范围
排除范围就是排除掉不需要的部门同步。下面举个例子,如果你的基域下存在多个OU的话,比如有:OU=上海,OU=浙江,OU=广东,OU=江苏如果您只想要同步上海浙江下的学员的话,那么搜索范围就可以配置为:OU=广东<and>OU=江苏

四、升级系统

用最新程序覆盖老的程序之后,执行下面的命令完成程序的升级:
docker compose down playedu document

docker compose build playedu

docker compose build document

docker compose up -d playedu document

sudo supervisorctl restart all

五、常见问题

5.1 如何查看基础镜像的Dockerfile

因为大陆封锁docker hub的原因,为了方便客户安装,我们交付给客户的compose.ymlDockerfile都使用了白书科技自行封装的镜像。如果您需要查看基础镜像的原始 Dockerfile的话可以查看交付程序目录下的docker/images目录,此目录下涵盖了所有我们二次封装的镜像Dockerfile

5.2 我如果想要拆分mysql,redis,kafka等中间件该如何操作?

首先,您按照您的标准安装好这些中间件,然后修改.env配置文件中的配置,下面给出拆分各个中间件之后所要修改的配置。

5.2.1 拆分MySQL

请修改.env中的下面配置,修改为您的MySQL连接信息:
DB_HOST=mysql
DB_PORT=3306
DB_NAME=playedu
DB_USER=root
DB_PASS=playeduxyz

DOC_DB_HOST=mysql
DOC_DB_PORT=3306
DOC_DB_NAME=document
DOC_DB_USER=root
DOC_DB_PASS=playeduxyz

5.2.2 拆分Redis

REDIS_HOST=redis
REDIS_PASS=F9nO2FzJ*%uDX58!
REDIS_PORT=6379
REDIS_DB=2

5.2.3 拆分Kafka

KAFKA_BOOTSTRAP_SERVERS=kafka:9092

5.3 MySQL数据库备份

# 将 playedu 数据库导出到 SQL 文件到当前目录
# -u 紧接着数据库账户
# -p 紧接着数据库账户密码
docker compose mysql mysqldump -uroot -pplayeduxyz playedu > ./playedu-backup.sql

5.4 转码程序的底层架构图

5.5 转码程序任务状态流程图


六、系统运维

6.1 服务重启

# 请注意,下面的命令都将在 playedu 程序根目录执行

# 重启 playedu-api 服务
docker compose restart playedu
# 停止 playedu-api 服务
docker compose stop playedu

# 重启转码服务
docker compose restart document
# 停止转码服务
docker compose stop document

6.2查看服务

# 请注意,下面的命令都将在 playedu 程序根目录执行

# 查看docker服务状态
sudo docker version

# 查看所有正在运行的容器
docker compose ps

 # 请注意,下面的命令都将在 playedu 程序根目录执行

6.2 查看日志

# 请注意,下面的命令都将在 playedu 程序根目录执行

# 查看 playedu-api 最近200行运行日志
docker compose logs -n 200 playedu

# 持续观测 playedu-api 的运行日志
docker compose logs -f -n 200 playedu

# 将 playedu-api 的日志导出本地 playedu.log
docker compose logs playedu > playedu.log

# 查看 playedu 转码服务最新200行日志
docker compose logs -n 200 document

6.3 登录数据库

# 请注意,下面的命令都将在 playedu 程序根目录执行

# .env文件中可以查询数据库配置信息

docker compose exec -it mysql /bin/bash

# 上述命令将进入 mysql 容器内的 bash 环境,输入下面命令登录进入 mysql 数据库
mysql -uroot -p

# 按照要求输入密码,回车即可进入 mysql 的命令行环境。执行下面命令进入 playedu 数据库
use playedu;

# 重置转码定时任务脚本 (更新转码任务,重启服务前,需要重置转码定时任务表数据)
SET FOREIGN_KEY_CHECKS = 0;
TRUNCATE TABLE resource_qrtz_blob_triggers ;
TRUNCATE TABLE resource_qrtz_calendars ;
TRUNCATE TABLE resource_qrtz_cron_triggers ;
TRUNCATE TABLE resource_qrtz_fired_triggers ;
TRUNCATE TABLE resource_qrtz_job_details ;
TRUNCATE TABLE resource_qrtz_locks ;
TRUNCATE TABLE resource_qrtz_paused_trigger_grps ;
TRUNCATE TABLE resource_qrtz_scheduler_state ;
TRUNCATE TABLE resource_qrtz_simple_triggers ;
TRUNCATE TABLE resource_qrtz_simprop_triggers ;
TRUNCATE TABLE resource_qrtz_triggers ;
SET FOREIGN_KEY_CHECKS = 1;