一、
什么是only office workspace
ONLYOFFICE协作空间,是Ascensio System SIA公司出品的,基于Web的,开源的,跨平台的,在线文档编辑和协作的解决方案
官网地址:ONLYOFFICE - 企业在线办公应用软件 | ONLYOFFICE
社区版only office下载地址:下载 ONLYOFFICE 产品的社区版本 | ONLYOFFICE
在线Office包含了最基本的办公三件套:文档编辑器、幻灯片编辑器和表格编辑器,额外还支持了pdf格式文件的创建和编辑功能,还有表单文件的创建编辑功能,并且,还提供了在线文档转换、在线文档预览、在线文档协作等功能。
最关键的是,多人在线实时协同办公功能,ONLYOFFICE协作空间创建一个个不同的虚拟房间,拉入不同的人进入虚拟房间就是一个团队一个team,每个人在团队中,可以创建自己的文档,也可以编辑其他人的文档,还可以查看其他人的文档,还可以和其他人分享自己的文档。
需要注意的是还有only office docspace,这个是和only office workspace相似的文档协助系统,但面向的用户侧重点不同,only office docspace是一个轻量化的系统,适用于敏捷开发的团队,而only office workspace是一个功能更多的,面向大中型企业所使用的在线文档系统,还拥有CRM、邮件等一体化管理。更有备份、存储、LDAP、SSO 等高级功能,是中小企业和开发者必备的在线文档系统利器
本文主要是介绍only office workspace和如何实现离线化快速安装部署,以及添加用户等等基本的业务操作介绍
二、
only office workspace组件介绍
only office workspace主要是由五个组件构成
-
第一个组件是MySQL数据库,该组件作用是备份功能以及文档持久化
-
第二个组件是elasticsearch,该组件的作用是提供文档检索,管理的功能
-
第三个组件是DS也就是onlyoffice/documentserver
- 该组件的作用是实现在线文档的编辑,查看文档的实际操作功能,特别需要注意的是该组件可以单独部署,但由于缺少CS组件,因此,无用户管理,此组件不依赖于其它组件,例如MySQL,elasticsearch
一、onlyoffice/documentserver的核心功能
-
在线文档编辑
-
支持主流办公格式:包括Microsoft Office(
.docx
、.xlsx
、.pptx
)、OpenDocument(.odt
、.ods
、.odp
)及PDF、HTML等,确保与现有文件兼容
-
-
实时协作编辑
-
多用户同步操作:多人同时编辑同一文档时,实时显示光标位置、文本修改及批注内容,通过WebSocket技术实现毫秒级同步。
-
权限分级控制:支持按角色设置编辑、评论或只读权限,确保分工明确5。
-
-
文档版本管理
-
自动保存历史版本:每次编辑生成快照,支持回溯至任意版本,避免误操作丢失数据
-
-
第四个组件是CS也就是onlyoffice/communityserver
onlyoffice/communityserver
(即ONLYOFFICE Community Server)是ONLYOFFICE Workspace的核心组件,负责整合并管理协作办公生态中的多类功能模块,实现企业级文档协作、项目管理、客户关系维护及通信的统一化处理。其核心作用可归纳为以下四大领域:
📁 1. 文档集中化与协作管理
-
实时协作编辑:与Document Server集成,实现多人同时编辑同一文档,实时显示他人光标位置,支持聊天讨论和批注功能
-
云存储集成:无缝对接Google Drive、Dropbox、OneDrive等主流云盘,实现跨平台文件同步与嵌入
📊 2. 项目全周期管理
-
甘特图与任务调度:可视化规划项目进度,设置里程碑、任务依赖关系及子任务分配
-
工时追踪与报告:记录任务耗时,自动生成项目进度报告,支持资源负载分析
-
自动化提醒:关联日历模块,自动推送任务截止提醒,减少进度延误
👥 3. 客户关系管理(CRM)
-
客户数据库:集中管理客户信息、联系人角色、交易历史及沟通记录,支持自定义字段扩展
-
销售流程自动化:
-
销售管道(Pipeline):自定义销售阶段(如“潜在客户→成交”),拖拽更新商机状态
-
Web-to-Lead表单:官网表单自动捕获潜在客户信息,生成CRM线索
- 集成通信工具:关联邮件和通话记录(如Twilio),自动同步至客户时间线。
-
✉️ 4. 邮件聚合与团队协作
-
统一收件箱:聚合多个邮箱账户(如QQ、Gmail),支持邮件收发、分类及搜索,避免多平台切换
-
团队协同工具:
-
日历共享:同步会议、演示日程,避免时间冲突
-
论坛/博客/投票:内置社区功能,支持内部知识分享与决策收集
-
即时通讯(需集成Talk组件):支持群组聊天与文件传输,补充异步沟通场景
-
-
第五个组件是onlyoffice/controlpanel,该组件是其它组件的后台管理组件,也就是平面管理组件
主要提供LDAP,SSO等等与其它外部系统交互的功能,该组件并不是特别的核心,但可以为整个系统锦上添花
总结一下这些组件,可以得出一个结论,关键核心组件是onlyoffice/documentserver和onlyoffice/communityserver,
其它组件基本都是围绕这两个组件来实现的,
onlyoffice/documentserver这个组件可以单独部署,其它组件不可以
三、
only office workspace的部署方式
only office workspace主要是通过线上官网下载shell脚本,然后通过调整脚本参数来实现不同的部署,主要是RPM/APT也就是二进制部署和docker镜像部署这两种方式,本文主要介绍通过shell脚本,借助docker 快速实现离线化部署
workspace-install.sh下载地址:
该脚本内容如下:
#!/bin/bash
set -e
# (c) Copyright Ascensio System Limited 2010-2021
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
# http://www.apache.org/licenses/LICENSE-2.0
# Unless required by applicable law or agreed to in writing,
# software distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and limitations under the License.
# You can contact Ascensio System SIA by email at sales@onlyoffice.com
PARAMETERS="";
DOCKER="";
HELP="false";
while [ "$1" != "" ]; do
case $1 in
-ls | --localscripts )
if [ "$2" == "true" ] || [ "$2" == false ]; then
PARAMETERS="$PARAMETERS ${1}";
LOCAL_SCRIPTS=$2
shift
fi
;;
"-?" | -h | --help )
HELP="true"
DOCKER="true"
PARAMETERS="$PARAMETERS -ht workspace-install.sh";
;;
esac
PARAMETERS="$PARAMETERS ${1}";
shift
done
PARAMETERS="$PARAMETERS -it WORKSPACE";
root_checking () {
if [ ! $( id -u ) -eq 0 ]; then
echo "To perform this action you must be logged in with root rights"
exit 1;
fi
}
command_exists () {
type "$1" &> /dev/null;
}
install_curl () {
if command_exists apt-get; then
apt-get -y update
apt-get -y -q install curl
elif command_exists yum; then
yum -y install curl
fi
if ! command_exists curl; then
echo "command curl not found"
exit 1;
fi
}
read_installation_method () {
echo "Select 'Y' to install ONLYOFFICE using Docker (recommended). Select 'N' to install it using RPM/DEB packages.";
echo "Please note, that in case you select RPM/DEB installation, you will need to manually install Mail Server and connect it to your ONLYOFFICE installation.";
echo "See instructions in our Help Center: http://helpcenter.onlyoffice.com/server/docker/mail/connect-mail-server-to-community-server-via-portal-settings.aspx";
read -p "Install with Docker [Y/N/C]? " choice
case "$choice" in
y|Y )
DOCKER="true";
;;
n|N )
DOCKER="false";
;;
c|C )
exit 0;
;;
* )
echo "Please, enter Y, N or C to cancel";
;;
esac
if [ "$DOCKER" == "" ]; then
read_installation_method;
fi
}
root_checking
if ! command_exists curl ; then
install_curl;
fi
if [ "$HELP" == "false" ]; then
read_installation_method;
fi
if [ "$DOCKER" == "true" ]; then
if [ "${LOCAL_SCRIPTS}" == "true" ]; then
bash install.sh ${PARAMETERS}
else
curl -s -O http://download.onlyoffice.com/install/install.sh
bash install.sh ${PARAMETERS}
rm install.sh
fi
else
if [ -f /etc/redhat-release ] ; then
DIST=$(cat /etc/redhat-release |sed s/\ release.*//);
REV=$(cat /etc/redhat-release | sed s/.*release\ // | sed s/\ .*//);
REV_PARTS=(${REV//\./ });
REV=${REV_PARTS[0]};
if [[ "${DIST}" == CentOS* ]] && [ ${REV} -lt 7 ]; then
echo "CentOS 7 or later is required";
exit 1;
fi
if [ "${LOCAL_SCRIPTS}" == "true" ]; then
bash install-RedHat.sh ${PARAMETERS}
else
curl -s -O http://download.onlyoffice.com/install/install-RedHat.sh
bash install-RedHat.sh ${PARAMETERS}
rm install-RedHat.sh
fi
elif [ -f /etc/debian_version ] ; then
if [ "${LOCAL_SCRIPTS}" == "true" ]; then
bash install-Debian.sh ${PARAMETERS}
else
curl -s -O http://download.onlyoffice.com/install/install-Debian.sh
bash install-Debian.sh ${PARAMETERS}
rm install-Debian.sh
fi
else
echo "Not supported OS";
exit 1;
fi
fi
可以看到,如果是docker方式部署安装only office workspace,那么跳转到curl -s -O http://download.onlyoffice.com/install/install.sh 这个命令下载名为install.sh的脚本,然后准备环境,并pull相关镜像后,启动所有相关服务
如果是redhat操作系统,那么跳转到curl -s -O http://download.onlyoffice.com/install/install-RedHat.sh这个命令下载名为install-RedHat.sh的脚本,并自动配置仓库然后开始rpm方式的安装,并最终启动所有相关服务
如果是debian操作系统,那么跳转到curl -s -O http://download.onlyoffice.com/install/install-Debian.sh这个命令下载名为install-Debian.sh的脚本,并自动配置仓库然后开始rpm方式的安装,并最终启动所有相关服务
install.sh脚本的内容(脚本非常长,小心查看):
#!/bin/bash
# (c) Copyright Ascensio System Limited 2010-2021
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
# http://www.apache.org/licenses/LICENSE-2.0
# Unless required by applicable law or agreed to in writing,
# software distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and limitations under the License.
# You can contact Ascensio System SIA by email at sales@onlyoffice.com
DISK_REQUIREMENTS=40960;
MEMORY_REQUIREMENTS=8000;
CORE_REQUIREMENTS=4;
PRODUCT="onlyoffice";
BASE_DIR="/app/$PRODUCT";
NETWORK="$PRODUCT";
SWAPFILE="/${PRODUCT}_swapfile";
MACHINEKEY_PARAM=$(echo "${PRODUCT}_CORE_MACHINEKEY" | awk '{print toupper($0)}');
COMMUNITY_CONTAINER_NAME="onlyoffice-community-server";
DOCUMENT_CONTAINER_NAME="onlyoffice-document-server";
MAIL_CONTAINER_NAME="onlyoffice-mail-server";
CONTROLPANEL_CONTAINER_NAME="onlyoffice-control-panel";
ELASTICSEARCH_CONTAINER_NAME="onlyoffice-elasticsearch";
MYSQL_CONTAINER_NAME="onlyoffice-mysql-server";
COMMUNITY_IMAGE_NAME="onlyoffice/communityserver";
DOCUMENT_IMAGE_NAME="onlyoffice/documentserver-ee";
MAIL_IMAGE_NAME="onlyoffice/mailserver";
CONTROLPANEL_IMAGE_NAME="onlyoffice/controlpanel";
ELASTICSEARCH_IMAGE_NAME="onlyoffice/elasticsearch";
MYSQL_IMAGE_NAME="mysql";
COMMUNITY_VERSION="";
DOCUMENT_VERSION="";
MAIL_VERSION="";
CONTROLPANEL_VERSION="";
ELASTICSEARCH_VERSION="7.16.3";
MYSQL_VERSION="5.5";
DOCUMENT_SERVER_HOST="";
ELASTICSEARCH_PORT="9200";
MAIL_SERVER_API_HOST="";
MAIL_SERVER_DB_HOST="";
MAIL_IMAPSYNC_START_DATE="$(date +"%Y-%m-%dT%H:%M:%S")";
MAIL_DOMAIN_NAME="";
DIST="";
REV="";
KERNEL="";
UPDATE="false";
HUB="";
USERNAME="";
PASSWORD="";
INSTALL_COMMUNITY_SERVER="true";
INSTALL_DOCUMENT_SERVER="true";
INSTALL_MAIL_SERVER="true";
INSTALL_ELASTICSEARCH="true";
INSTALL_CONTROLPANEL="true";
USE_AS_EXTERNAL_SERVER="false";
PARTNER_DATA_FILE="";
INSTALLATION_TYPE="WORKSPACE_ENTERPRISE";
MAKESWAP="true";
RESTART_COMMUNITY_SERVER="false";
MOVE_COMMUNITY_SERVER_DATABASE="false";
ACTIVATE_COMMUNITY_SERVER_TRIAL="false";
MYSQL_PORT="3306";
MYSQL_DATABASE="$PRODUCT";
MYSQL_MAIL_DATABASE="${PRODUCT}_mailserver";
MYSQL_MAIL_ROOT_PASSWORD="Isadmin123";
MYSQL_MAIL_USER="mail_admin";
MYSQL_ROOT_USER="root";
MYSQL_ROOT_PASSWORD="my-secret-pw";
MYSQL_USER="${PRODUCT}_user";
MYSQL_PASSWORD="${PRODUCT}_pass";
MYSQL_HOST="";
HELP_TARGET="install.sh";
JWT_ENABLED="";
JWT_SECRET="";
CORE_MACHINEKEY="";
SKIP_HARDWARE_CHECK="false";
SKIP_VERSION_CHECK="false";
SKIP_DOMAIN_CHECK="false";
COMMUNITY_PORT=80;
while [ "$1" != "" ]; do
case $1 in
-ci | --communityimage )
if [ "$2" != "" ]; then
COMMUNITY_IMAGE_NAME=$2
shift
fi
;;
-di | --documentimage )
if [ "$2" != "" ]; then
DOCUMENT_IMAGE_NAME=$2
shift
fi
;;
-mi | --mailimage )
if [ "$2" != "" ]; then
MAIL_IMAGE_NAME=$2
shift
fi
;;
-cpi | --controlpanelimage )
if [ "$2" != "" ]; then
CONTROLPANEL_IMAGE_NAME=$2
shift
fi
;;
-mysqli | --mysqlimage )
if [ "$2" != "" ]; then
MYSQL_IMAGE_NAME=$2
shift
fi
;;
-dip | --documentserverip )
if [ "$2" != "" ]; then
DOCUMENT_SERVER_HOST=$2
shift
fi
;;
-mip | --mailserverip )
if [ "$2" != "" ]; then
MAIL_SERVER_API_HOST=$2
shift
fi
;;
-mdbip | --mailserverdbip )
if [ "$2" != "" ]; then
MAIL_SERVER_DB_HOST=$2
shift
fi
;;
-cv | --communityversion )
if [ "$2" != "" ]; then
COMMUNITY_VERSION=$2
shift
fi
;;
-dv | --documentversion )
if [ "$2" != "" ]; then
DOCUMENT_VERSION=$2
shift
fi
;;
-mv | --mailversion )
if [ "$2" != "" ]; then
MAIL_VERSION=$2
shift
fi
;;
-cpv | --controlpanelversion )
if [ "$2" != "" ]; then
CONTROLPANEL_VERSION=$2
shift
fi
;;
-md | --maildomain )
if [ "$2" != "" ]; then
MAIL_DOMAIN_NAME=$2
shift
fi
;;
-u | --update )
if [ "$2" != "" ]; then
UPDATE=$2
shift
fi
;;
-hub | --hub )
if [ "$2" != "" ]; then
HUB=$2
shift
fi
;;
-un | --username )
if [ "$2" != "" ]; then
USERNAME=$2
shift
fi
;;
-p | --password )
if [ "$2" != "" ]; then
PASSWORD=$2
shift
fi
;;
-ics | --installcommunityserver )
if [ "$2" != "" ]; then
INSTALL_COMMUNITY_SERVER=$2
shift
fi
;;
-ids | --installdocumentserver )
if [ "$2" != "" ]; then
INSTALL_DOCUMENT_SERVER=$2
shift
fi
;;
-ims | --installmailserver )
if [ "$2" != "" ]; then
INSTALL_MAIL_SERVER=$2
shift
fi
;;
-icp | --installcontrolpanel )
if [ "$2" != "" ]; then
INSTALL_CONTROLPANEL=$2
shift
fi
;;
-es | --useasexternalserver )
if [ "$2" != "" ]; then
USE_AS_EXTERNAL_SERVER=$2
shift
fi
;;
-pdf | --partnerdatafile )
if [ "$2" != "" ]; then
PARTNER_DATA_FILE=$2
shift
fi
;;
-it | --installation_type )
if [ "$2" != "" ]; then
INSTALLATION_TYPE=$(echo "$2" | awk '{print toupper($0)}');
shift
fi
;;
-ms | --makeswap )
if [ "$2" != "" ]; then
MAKESWAP=$2
shift
fi
;;
-ht | --helptarget )
if [ "$2" != "" ]; then
HELP_TARGET=$2
shift
fi
;;
-mysqlprt | --mysqlport )
if [ "$2" != "" ]; then
MYSQL_PORT=$2
shift
fi
;;
-mysqld | --mysqldatabase )
if [ "$2" != "" ]; then
MYSQL_DATABASE=$2
shift
fi
;;
-mysqlmd | --mysqlmaildatabase )
if [ "$2" != "" ]; then
MYSQL_MAIL_DATABASE=$2
shift
fi
;;
-mysqlmp | --mysqlmailpassword )
if [ "$2" != "" ]; then
MYSQL_MAIL_ROOT_PASSWORD=$2
shift
fi
;;
-mysqlmu | --mysqlmailuser )
if [ "$2" != "" ]; then
MYSQL_MAIL_USER=$2
shift
fi
;;
-mysqlru | --mysqlrootuser )
if [ "$2" != "" ]; then
MYSQL_ROOT_USER=$2
shift
fi
;;
-mysqlrp | --mysqlrootpassword )
if [ "$2" != "" ]; then
MYSQL_ROOT_PASSWORD=$2
shift
fi
;;
-mysqlu | --mysqluser )
if [ "$2" != "" ]; then
MYSQL_USER=$2
shift
fi
;;
-mysqlp | --mysqlpassword )
if [ "$2" != "" ]; then
MYSQL_PASSWORD=$2
shift
fi
;;
-mysqlh | --mysqlhost )
if [ "$2" != "" ]; then
MYSQL_HOST=$2
shift
fi
;;
-skiphc | --skiphardwarecheck )
if [ "$2" != "" ]; then
SKIP_HARDWARE_CHECK=$2
shift
fi
;;
-skipvc | --skipversioncheck )
if [ "$2" != "" ]; then
SKIP_VERSION_CHECK=$2
shift
fi
;;
-skipdc | --skipdomaincheck )
if [ "$2" != "" ]; then
SKIP_DOMAIN_CHECK=$2
shift
fi
;;
-cp | --communityport )
if [ "$2" != "" ]; then
COMMUNITY_PORT=$2
shift
fi
;;
-mk | --machinekey )
if [ "$2" != "" ]; then
CORE_MACHINEKEY=$2
shift
fi
;;
-esi | --elasticsearchimage )
if [ "$2" != "" ]; then
ELASTICSEARCH_IMAGE_NAME=$2
shift
fi
;;
-esv | --elasticsearchversion )
if [ "$2" != "" ]; then
ELASTICSEARCH_VERSION=$2
shift
fi
;;
-esh | --elasticsearchhost )
if [ "$2" != "" ]; then
ELASTICSEARCH_HOST=$2
shift
fi
;;
-ies | --installelasticsearch )
if [ "$2" != "" ]; then
INSTALL_ELASTICSEARCH=$2
shift
fi
;;
-esp | --elasticsearchport )
if [ "$2" != "" ]; then
ELASTICSEARCH_PORT=$2
shift
fi
;;
-je | --jwtenabled )
if [ "$2" != "" ]; then
JWT_ENABLED=$2
shift
fi
;;
-jh | --jwtheader )
if [ "$2" != "" ]; then
JWT_HEADER=$2
shift
fi
;;
-js | --jwtsecret )
if [ "$2" != "" ]; then
JWT_SECRET=$2
shift
fi
;;
-? | -h | --help )
echo " Usage: bash $HELP_TARGET [PARAMETER] [[PARAMETER], ...]"
echo
echo " Parameters:"
echo " -ci, --communityimage community image name or .tar.gz file path"
echo " -di, --documentimage document image name or .tar.gz file path"
echo " -mi, --mailimage mail image name or .tar.gz file path"
echo " -esi, --elasticsearchimage elasticsearch image name or .tar.gz file path"
echo " -cpi, --controlpanelimage control panel image name or .tar.gz file path"
echo " -mysqli, --mysqlimage mysql image name or .tar.gz file path"
echo " -cv, --communityversion community version"
echo " -dv, --documentversion document version"
echo " -dip, --documentserverip document server ip"
echo " -esv, --elasticsearchversion elasticsearch version"
echo " -esh, --elasticsearchhost elasticsearch server host"
echo " -msp, --elasticsearchport elasticsearch server port"
echo " -mv, --mailversion mail version"
echo " -mip, --mailserverip mail server ip"
echo " -mdbip, --mailserverdbip mail server db ip"
echo " -cpv, --controlpanelversion control panel version"
echo " -md, --maildomain mail domail name"
echo " -u, --update use to update existing components (true|false)"
echo " -hub, --hub dockerhub name"
echo " -un, --username dockerhub username"
echo " -p, --password dockerhub password"
echo " -ics, --installcommunityserver install or update community server (true|false|pull)"
echo " -ids, --installdocumentserver install or update document server (true|false|pull)"
echo " -ims, --installmailserver install or update mail server (true|false|pull)"
echo " -ies, --installelasticsearch install or update elasticsearch (true|false|pull)"
echo " -icp, --installcontrolpanel install or update control panel (true|false|pull)"
echo " -es, --useasexternalserver use as external server (true|false)"
echo " -pdf, --partnerdatafile partner data file"
echo " -it, --installation_type installation type (GROUPS|WORKSPACE|WORKSPACE_ENTERPRISE)"
echo " -ms, --makeswap make swap file (true|false)"
echo " -mysqlh, --mysqlhost mysql server host"
echo " -mysqlprt, --mysqlport mysql server port"
echo " -mysqlru, --mysqlrootuser mysql server root user"
echo " -mysqlrp, --mysqlrootpassword mysql server root password"
echo " -mysqld, --mysqldatabase community server database name"
echo " -mysqlu, --mysqluser community server database user"
echo " -mysqlp, --mysqlpassword community server database password"
echo " -mysqlmd, --mysqlmaildatabase mail server database name"
echo " -mysqlmu, --mysqlmailuser mail server database user"
echo " -mysqlmp, --mysqlmailpassword mail server database password"
echo " -skiphc, --skiphardwarecheck skip hardware check (true|false)"
echo " -skipvc, --skipversioncheck skip version check while update (true|false)"
echo " -skipdc, --skipdomaincheck skip domain check when installing mail server (true|false)"
echo " -cp, --communityport community port (default value 80)"
echo " -mk, --machinekey setting for core.machinekey"
echo " -je, --jwtenabled specifies the enabling the JWT validation (true|false)"
echo " -jh, --jwtheader defines the http header that will be used to send the JWT"
echo " -js, --jwtsecret defines the secret key to validate the JWT in the request"
echo " -?, -h, --help this help"
echo
echo " Examples"
echo " Install all the solution components:"
echo " bash $HELP_TARGET -md yourdomain.com"
echo
echo " Install all the components without Mail Server:"
echo " bash $HELP_TARGET -ims false"
echo
echo " Install Document Server only. Skip the installation of Mail Server, Community Server and Control Panel:"
echo " bash $HELP_TARGET -ics false -ids true -icp false -ims false -es true"
echo
echo " Install Mail Server only. Skip the installation of Document Server, Community Server and Control Panel:"
echo " bash $HELP_TARGET -ics false -ids false -icp false -ims true -md yourdomain.com -es true"
echo
echo " Install Community Server with Control Panel and connect it with Document Server installed on a different machine which has the 192.168.3.202 IP address:"
echo " bash $HELP_TARGET -ics true -icp true -ids false -ims false -dip 192.168.3.202"
echo
echo " Update all installed components. Stop the containers that need to be updated, remove them and run the latest versions of the corresponding components. The portal data should be picked up automatically:"
echo " bash $HELP_TARGET -u true"
echo
echo " Update Document Server only to version 4.4.2.20 and skip the update for all other components:"
echo " bash $HELP_TARGET -u true -dv 4.4.2.20 -ics false -icp false -ims false"
echo
echo " Update Community Server only to version 9.1.0.393 and skip the update for all other components:"
echo " bash $HELP_TARGET -u true -cv 9.1.0.393 -ids false -icp false -ims false"
echo
echo " Update Mail Server only to version 1.6.27 and skip the update for all other components:"
echo " bash $HELP_TARGET -u true -mv 1.6.27 -ics false -ids false -icp false"
echo
echo " Update Control Panel only to version 2.1.0.93 and skip the update for all other components:"
echo " bash $HELP_TARGET -u true -cpv 2.1.0.93 -ics false -ids false -ims false"
echo
exit 0
;;
* )
echo "Unknown parameter $1" 1>&2
exit 1
;;
esac
shift
done
root_checking () {
if [ ! $( id -u ) -eq 0 ]; then
echo "To perform this action you must be logged in with root rights"
exit 1;
fi
}
command_exists () {
type "$1" &> /dev/null;
}
file_exists () {
if [ -z "$1" ]; then
echo "file path is empty"
exit 1;
fi
if [ -f "$1" ]; then
return 0; #true
else
return 1; #false
fi
}
install_curl () {
if command_exists apt-get; then
apt-get -y update
apt-get -y -q install curl
elif command_exists yum; then
yum -y install curl
fi
if ! command_exists curl; then
echo "command curl not found"
exit 1;
fi
}
install_jq () {
if command_exists apt-get; then
apt-get -y update
apt-get -y -q install jq
elif command_exists yum; then
rpm -ivh https://dl.fedoraproject.org/pub/epel/epel-release-latest-$REV.noarch.rpm || true
yum -y install jq
fi
if ! command_exists jq; then
echo "command jq not found"
exit 1;
fi
}
install_netstat () {
if command_exists apt-get; then
apt-get -y update
apt-get -y -q install net-tools
elif command_exists yum; then
yum -y install net-tools
fi
if ! command_exists netstat; then
echo "command netstat not found"
exit 1;
fi
}
to_lowercase () {
echo "$1" | awk '{print tolower($0)}'
}
trim () {
echo -e "$1" | sed -e 's/^[[:space:]]*//' -e 's/[[:space:]]*$//'
}
get_os_info () {
OS=`to_lowercase \`uname\``
if [ "${OS}" == "windowsnt" ]; then
echo "Not supported OS";
exit 1;
elif [ "${OS}" == "darwin" ]; then
echo "Not supported OS";
exit 1;
else
OS=`uname`
if [ "${OS}" == "SunOS" ] ; then
echo "Not supported OS";
exit 1;
elif [ "${OS}" == "AIX" ] ; then
echo "Not supported OS";
exit 1;
elif [ "${OS}" == "Linux" ] ; then
MACH=`uname -m`
if [ "${MACH}" != "x86_64" ]; then
echo "Currently only supports 64bit OS's";
exit 1;
fi
KERNEL=`uname -r`
if [ -f /etc/redhat-release ] ; then
CONTAINS=$(cat /etc/redhat-release | { grep -sw release || true; });
if [[ -n ${CONTAINS} ]]; then
DIST=`cat /etc/redhat-release |sed s/\ release.*//`
REV=`cat /etc/redhat-release | grep -oP '(?<=release )\d+'`
else
DIST=`cat /etc/os-release | grep -sw 'ID' | awk -F= '{ print $2 }' | sed -e 's/^"//' -e 's/"$//'`
REV=`cat /etc/os-release | grep -sw 'VERSION_ID' | awk -F= '{ print $2 }' | sed -e 's/^"//' -e 's/"$//'`
fi
elif [ -f /etc/SuSE-release ] ; then
REV=`cat /etc/os-release | grep '^VERSION_ID' | awk -F= '{ print $2 }' | sed -e 's/^"//' -e 's/"$//'`
DIST='SuSe'
elif [ -f /etc/debian_version ] ; then
REV=`cat /etc/debian_version`
DIST='Debian'
if [ -f /etc/lsb-release ] ; then
DIST=`cat /etc/lsb-release | grep '^DISTRIB_ID' | awk -F= '{ print $2 }'`
REV=`cat /etc/lsb-release | grep '^DISTRIB_RELEASE' | awk -F= '{ print $2 }'`
elif [ -f /etc/lsb_release ] || [ -f /usr/bin/lsb_release ] ; then
DIST=`lsb_release -a 2>&1 | grep 'Distributor ID:' | awk -F ":" '{print $2 }'`
REV=`lsb_release -a 2>&1 | grep 'Release:' | awk -F ":" '{print $2 }'`
fi
elif [ -f /etc/os-release ] ; then
DIST=`cat /etc/os-release | grep -sw 'ID' | awk -F= '{ print $2 }' | sed -e 's/^"//' -e 's/"$//'`
REV=`cat /etc/os-release | grep -sw 'VERSION_ID' | awk -F= '{ print $2 }' | sed -e 's/^"//' -e 's/"$//'`
fi
fi
DIST=$(trim "$DIST");
REV=$(trim $REV);
fi
}
check_os_info () {
if [[ -z ${KERNEL} || -z ${DIST} || -z ${REV} ]]; then
echo "$KERNEL, $DIST, $REV";
echo "Not supported OS";
exit 1;
fi
}
check_kernel () {
MIN_NUM_ARR=(3 10 0);
CUR_NUM_ARR=();
CUR_STR_ARR=$(echo $KERNEL | grep -Po "[0-9]+\.[0-9]+\.[0-9]+" | tr "." " ");
for CUR_STR_ITEM in $CUR_STR_ARR
do
CUR_NUM_ARR=(${CUR_NUM_ARR[@]} $CUR_STR_ITEM)
done
INDEX=0;
while [[ $INDEX -lt 3 ]]; do
if [ ${CUR_NUM_ARR[INDEX]} -lt ${MIN_NUM_ARR[INDEX]} ]; then
echo "Not supported OS Kernel"
exit 1;
elif [ ${CUR_NUM_ARR[INDEX]} -gt ${MIN_NUM_ARR[INDEX]} ]; then
INDEX=3
fi
(( INDEX++ ))
done
}
check_hardware () {
AVAILABLE_DISK_SPACE=$(df -m / | tail -1 | awk '{ print $4 }');
if [ ${AVAILABLE_DISK_SPACE} -lt ${DISK_REQUIREMENTS} ]; then
echo "Minimal requirements are not met: need at least $DISK_REQUIREMENTS MB of free HDD space"
exit 1;
fi
TOTAL_MEMORY=$(free --mega | grep -oP '\d+' | head -n 1);
if [ ${TOTAL_MEMORY} -lt ${MEMORY_REQUIREMENTS} ]; then
echo "Minimal requirements are not met: need at least $MEMORY_REQUIREMENTS MB of RAM"
exit 1;
fi
CPU_CORES_NUMBER=$(cat /proc/cpuinfo | grep processor | wc -l);
if [ ${CPU_CORES_NUMBER} -lt ${CORE_REQUIREMENTS} ]; then
echo "The system does not meet the minimal hardware requirements. CPU with at least $CORE_REQUIREMENTS cores is required"
exit 1;
fi
}
make_swap () {
DISK_REQUIREMENTS=6144; #6Gb free space
MEMORY_REQUIREMENTS=16000; #RAM ~16Gb
AVAILABLE_DISK_SPACE=$(df -m / | tail -1 | awk '{ print $4 }');
TOTAL_MEMORY=$(free --mega | grep -oP '\d+' | head -n 1);
EXIST=$(swapon -s | awk '{ print $1 }' | { grep -x ${SWAPFILE} || true; });
if [[ -z $EXIST ]] && [ ${TOTAL_MEMORY} -lt ${MEMORY_REQUIREMENTS} ] && [ ${AVAILABLE_DISK_SPACE} -gt ${DISK_REQUIREMENTS} ]; then
if [ "${DIST}" == "Ubuntu" ] || [ "${DIST}" == "Debian" ]; then
fallocate -l 6G ${SWAPFILE}
else
dd if=/dev/zero of=${SWAPFILE} count=6144 bs=1MiB
fi
chmod 600 ${SWAPFILE}
mkswap ${SWAPFILE}
swapon ${SWAPFILE}
echo "$SWAPFILE none swap sw 0 0" >> /etc/fstab
fi
}
check_ports () {
RESERVED_PORTS=(443 5222 25 143 587 4190 8081 3306);
ARRAY_PORTS=();
USED_PORTS="";
if ! command_exists netstat; then
install_netstat
fi
if [ "${COMMUNITY_PORT//[0-9]}" = "" ]; then
for RESERVED_PORT in "${RESERVED_PORTS[@]}"
do
if [ "$RESERVED_PORT" -eq "$COMMUNITY_PORT" ] ; then
echo "Community port $COMMUNITY_PORT is reserved. Select another port"
exit 1;
fi
done
else
echo "Invalid community port $COMMUNITY_PORT"
exit 1;
fi
if [ "$INSTALL_COMMUNITY_SERVER" == "true" ]; then
ARRAY_PORTS=(${ARRAY_PORTS[@]} "$COMMUNITY_PORT" "443" "5222");
elif [ "$INSTALL_DOCUMENT_SERVER" == "true" ]; then
if [ "${USE_AS_EXTERNAL_SERVER}" == "true" ]; then
ARRAY_PORTS=(${ARRAY_PORTS[@]} "$COMMUNITY_PORT" "443");
fi
fi
if [ "$INSTALL_MAIL_SERVER" == "true" ]; then
ARRAY_PORTS=(${ARRAY_PORTS[@]} "25" "143" "587", "465", "993", "995", "4190");
if [ "${USE_AS_EXTERNAL_SERVER}" == "true" ]; then
ARRAY_PORTS=(${ARRAY_PORTS[@]} "8081");
if [[ -z ${MYSQL_HOST} ]]; then
ARRAY_PORTS=(${ARRAY_PORTS[@]} "3306");
fi
fi
fi
for PORT in "${ARRAY_PORTS[@]}"
do
REGEXP=":$PORT$"
CHECK_RESULT=$(netstat -lnt | awk '{print $4}' | { grep $REGEXP || true; })
if [[ $CHECK_RESULT != "" ]]; then
if [[ $USED_PORTS != "" ]]; then
USED_PORTS="$USED_PORTS, $PORT"
else
USED_PORTS="$PORT"
fi
fi
done
if [[ $USED_PORTS != "" ]]; then
echo "The following TCP Ports must be available: $USED_PORTS"
exit 1;
fi
}
check_docker_version () {
CUR_FULL_VERSION=$(docker -v | cut -d ' ' -f3 | cut -d ',' -f1);
CUR_VERSION=$(echo $CUR_FULL_VERSION | cut -d '-' -f1);
CUR_EDITION=$(echo $CUR_FULL_VERSION | cut -d '-' -f2);
if [ "${CUR_EDITION}" == "ce" ] || [ "${CUR_EDITION}" == "ee" ]; then
return 0;
fi
if [ "${CUR_VERSION}" != "${CUR_EDITION}" ]; then
echo "Unspecific docker version"
exit 1;
fi
MIN_NUM_ARR=(1 10 0);
CUR_NUM_ARR=();
CUR_STR_ARR=$(echo $CUR_VERSION | grep -Po "[0-9]+\.[0-9]+\.[0-9]+" | tr "." " ");
for CUR_STR_ITEM in $CUR_STR_ARR
do
CUR_NUM_ARR=(${CUR_NUM_ARR[@]} $CUR_STR_ITEM)
done
INDEX=0;
while [[ $INDEX -lt 3 ]]; do
if [ ${CUR_NUM_ARR[INDEX]} -lt ${MIN_NUM_ARR[INDEX]} ]; then
echo "The outdated Docker version has been found. Please update to the latest version."
exit 1;
elif [ ${CUR_NUM_ARR[INDEX]} -gt ${MIN_NUM_ARR[INDEX]} ]; then
return 0;
fi
(( INDEX++ ))
done
}
install_docker_using_script () {
if ! command_exists curl ; then
install_curl;
fi
curl -fsSL https://get.docker.com -o get-docker.sh
sh get-docker.sh
rm get-docker.sh
}
install_docker () {
if [ "${DIST}" == "Ubuntu" ] || [ "${DIST}" == "Debian" ] || [[ "${DIST}" == CentOS* ]] || [ "${DIST}" == "Fedora" ]; then
install_docker_using_script
systemctl start docker
systemctl enable docker
elif [ "${DIST}" == "Red Hat Enterprise Linux Server" ]; then
echo ""
echo "Your operating system does not allow Docker CE installation."
echo "You can install Docker EE using the manual here - https://docs.docker.com/engine/installation/linux/rhel/"
echo ""
exit 1;
elif [ "${DIST}" == "SuSe" ]; then
echo ""
echo "Your operating system does not allow Docker CE installation."
echo "You can install Docker EE using the manual here - https://docs.docker.com/engine/installation/linux/suse/"
echo ""
exit 1;
elif [ "${DIST}" == "altlinux" ]; then
apt-get -y install docker-io
chkconfig docker on
service docker start
systemctl enable docker
else
echo ""
echo "Docker could not be installed automatically."
echo "Please use this official instruction https://docs.docker.com/engine/installation/linux/other/ for its manual installation."
echo ""
exit 1;
fi
if ! command_exists docker ; then
echo "error while installing docker"
exit 1;
fi
}
docker_login () {
if [[ -n ${USERNAME} && -n ${PASSWORD} ]]; then
docker login ${HUB} --username ${USERNAME} --password ${PASSWORD}
fi
}
make_directories () {
mkdir -p "$BASE_DIR/setup";
mkdir -p "$BASE_DIR/DocumentServer/data";
mkdir -p "$BASE_DIR/DocumentServer/logs";
mkdir -p "$BASE_DIR/DocumentServer/fonts";
mkdir -p "$BASE_DIR/DocumentServer/forgotten";
mkdir -p "$BASE_DIR/MailServer/data/certs";
mkdir -p "$BASE_DIR/MailServer/logs";
mkdir -p "$BASE_DIR/CommunityServer/data";
mkdir -p "$BASE_DIR/CommunityServer/data/certs";
mkdir -p "$BASE_DIR/CommunityServer/data/certs/tmp";
mkdir -p "$BASE_DIR/CommunityServer/logs";
mkdir -p "$BASE_DIR/ControlPanel/data";
mkdir -p "$BASE_DIR/ControlPanel/logs";
mkdir -p "$BASE_DIR/mysql/conf.d";
mkdir -p "$BASE_DIR/mysql/data";
mkdir -p "$BASE_DIR/mysql/initdb";
mkdir -p "$BASE_DIR/mysql/logs";
mkdir -p "$BASE_DIR/mysql/.private";
}
get_available_version () {
if [[ -z "$1" ]]; then
echo "image name is empty";
exit 1;
fi
if ! command_exists curl ; then
install_curl >/dev/null 2>&1
fi
if ! command_exists jq ; then
install_jq >/dev/null 2>&1
fi
CREDENTIALS="";
AUTH_HEADER="";
TAGS_RESP="";
if [[ -n ${HUB} ]]; then
DOCKER_CONFIG="$HOME/.docker/config.json";
if [[ -f "$DOCKER_CONFIG" ]]; then
CREDENTIALS=$(jq -r '.auths."'$HUB'".auth' < "$DOCKER_CONFIG");
if [ "$CREDENTIALS" == "null" ]; then
CREDENTIALS="";
fi
fi
if [[ -z ${CREDENTIALS} && -n ${USERNAME} && -n ${PASSWORD} ]]; then
CREDENTIALS=$(echo -n "$USERNAME:$PASSWORD" | base64);
fi
if [[ -n ${CREDENTIALS} ]]; then
AUTH_HEADER="Authorization: Basic $CREDENTIALS";
fi
REPO=$(echo $1 | sed "s/$HUB\///g");
TAGS_RESP=$(curl -s -H "$AUTH_HEADER" -X GET https://$HUB/v2/$REPO/tags/list);
TAGS_RESP=$(echo $TAGS_RESP | jq -r '.tags')
else
if [[ -n ${USERNAME} && -n ${PASSWORD} ]]; then
CREDENTIALS="{\"username\":\"$USERNAME\",\"password\":\"$PASSWORD\"}";
fi
if [[ -n ${CREDENTIALS} ]]; then
LOGIN_RESP=$(curl -s -H "Content-Type: application/json" -X POST -d "$CREDENTIALS" https://hub.docker.com/v2/users/login/);
TOKEN=$(echo $LOGIN_RESP | jq -r '.token');
AUTH_HEADER="Authorization: JWT $TOKEN";
sleep 1;
fi
TAGS_RESP=$(curl -s -H "$AUTH_HEADER" -X GET https://hub.docker.com/v2/repositories/$1/tags/);
TAGS_RESP=$(echo $TAGS_RESP | jq -r '.results[].name')
fi
VERSION_REGEX_1="[0-9]+\.[0-9]+\.[0-9]+"
VERSION_REGEX_2="[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+"
TAG_LIST=""
for item in $TAGS_RESP
do
if [[ $item =~ $VERSION_REGEX_1 ]] || [[ $item =~ $VERSION_REGEX_2 ]]; then
TAG_LIST="$item,$TAG_LIST"
fi
done
LATEST_TAG=$(echo $TAG_LIST | tr ',' '\n' | sort -t. -k 1,1n -k 2,2n -k 3,3n -k 4,4n | awk '/./{line=$0} END{print line}');
echo "$LATEST_TAG" | sed "s/\"//g"
}
get_current_image_name () {
if [[ -z "$1" ]]; then
echo "container name is empty";
exit 1;
fi
CONTAINER_IMAGE=$(docker inspect --format='{{.Config.Image}}' $1)
CONTAINER_IMAGE_PARTS=($(echo $CONTAINER_IMAGE | tr ":" "\n"))
echo ${CONTAINER_IMAGE_PARTS[0]}
}
get_current_image_version () {
if [[ -z "$1" ]]; then
echo "container name is empty";
exit 1;
fi
CONTAINER_IMAGE=$(docker inspect --format='{{.Config.Image}}' $1)
CONTAINER_IMAGE_PARTS=($(echo $CONTAINER_IMAGE | tr ":" "\n"))
echo ${CONTAINER_IMAGE_PARTS[1]}
}
check_bindings () {
if [[ -z "$1" ]]; then
echo "container id is empty";
exit 1;
fi
binds=$(docker inspect --format='{{range $p,$conf:=.HostConfig.Binds}}{{$conf}};{{end}}' $1)
volumes=$(docker inspect --format='{{range $p,$conf:=.Config.Volumes}}{{$p}};{{end}}' $1)
arrBinds=$(echo $binds | tr ";" "\n")
arrVolumes=$(echo $volumes | tr ";" "\n")
bindsCorrect=1
if [[ -n "$2" ]]; then
exceptions=$(echo $2 | tr "," "\n")
for ex in ${exceptions[@]}
do
arrVolumes=(${arrVolumes[@]/$ex})
done
fi
for volume in $arrVolumes
do
bindExist=0
for bind in $arrBinds
do
bind=($(echo $bind | tr ":" " "))
if [ "${bind[1]}" == "${volume}" ]; then
bindExist=1
fi
done
if [ "$bindExist" == "0" ]; then
bindsCorrect=0
echo "${volume} not binded"
fi
done
if [ "$bindsCorrect" == "0" ]; then
exit 1;
fi
}
change_mysql_credentials () {
while ! docker exec -it ${MYSQL_CONTAINER_NAME} mysqladmin ping --silent; do
echo "wait for $MYSQL_CONTAINER_NAME"
sleep 5
done
docker exec -it ${MYSQL_CONTAINER_NAME} mysqladmin password "$MYSQL_ROOT_PASSWORD"
docker exec -i ${MYSQL_CONTAINER_NAME} mysql -u ${MYSQL_ROOT_USER} -p${MYSQL_ROOT_PASSWORD} < ${BASE_DIR}/mysql/initdb/setup.sql
}
install_mysql_server () {
MYSQL_SERVER_ID=$(get_container_id "$MYSQL_CONTAINER_NAME");
RUN_MYSQL_SERVER="true";
if [[ -n ${MYSQL_SERVER_ID} ]]; then
RUN_MYSQL_SERVER="false";
echo "ONLYOFFICE MYSQL SERVER is already installed."
if [[ "$(awk -F. '{ printf("%d%03d%03d%03d", $1,$2,$3,$4); }' <<< $MYSQL_VERSION)" -lt "8000000000" ]]; then
if ! grep -q "tls_version" ${BASE_DIR}/mysql/conf.d/${PRODUCT}.cnf; then
echo "tls_version = TLSv1.2" >> ${BASE_DIR}/mysql/conf.d/${PRODUCT}.cnf
echo "" > $BASE_DIR/CommunityServer/data/.private/release_date
else
sed -i "s/tls_version.*/tls_version = TLSv1.2/" ${BASE_DIR}/mysql/conf.d/${PRODUCT}.cnf
fi
fi
if file_exists "${BASE_DIR}/mysql/initdb/setup.sql"; then
if grep -q "caching_sha2_password" ${BASE_DIR}/mysql/initdb/setup.sql; then
sed -i 's/caching_sha2_password/mysql_native_password/g' ${BASE_DIR}/mysql/initdb/setup.sql
elif ! grep -q "mysql_native_password" ${BASE_DIR}/mysql/initdb/setup.sql; then
sed -i 's/IDENTIFIED BY/IDENTIFIED WITH mysql_native_password BY/g' ${BASE_DIR}/mysql/initdb/setup.sql
fi
fi
docker restart ${MYSQL_SERVER_ID};
fi
if [ "$RUN_MYSQL_SERVER" == "true" ]; then
if ! file_exists ${BASE_DIR}/mysql/conf.d/${PRODUCT}.cnf; then
echo "[mysqld]
sql_mode = 'NO_ENGINE_SUBSTITUTION'
max_connections = 1000
max_allowed_packet = 1048576000
group_concat_max_len = 2048
log-error = /var/log/mysql/error.log" > ${BASE_DIR}/mysql/conf.d/${PRODUCT}.cnf
[[ "$(awk -F. '{ printf("%d%03d%03d%03d", $1,$2,$3,$4); }' <<< $MYSQL_VERSION)" -lt "8000000000" ]] && echo "tls_version = TLSv1.2" >> ${BASE_DIR}/mysql/conf.d/${PRODUCT}.cnf
chmod 0644 ${BASE_DIR}/mysql/conf.d/${PRODUCT}.cnf
fi
if ! file_exists ${BASE_DIR}/mysql/initdb/setup.sql; then
echo "CREATE USER '$MYSQL_USER'@'%' IDENTIFIED WITH mysql_native_password BY '$MYSQL_PASSWORD';
CREATE USER '$MYSQL_MAIL_USER'@'%' IDENTIFIED WITH mysql_native_password BY '$MYSQL_MAIL_ROOT_PASSWORD';
ALTER USER 'root'@'%' IDENTIFIED WITH mysql_native_password BY '$MYSQL_ROOT_PASSWORD';
ALTER USER 'root'@'localhost' IDENTIFIED WITH mysql_native_password BY '$MYSQL_ROOT_PASSWORD';
GRANT ALL PRIVILEGES ON *.* TO '$MYSQL_ROOT_USER'@'%';
GRANT ALL PRIVILEGES ON *.* TO '$MYSQL_USER'@'%';
GRANT ALL PRIVILEGES ON *.* TO '$MYSQL_MAIL_USER'@'%';
FLUSH PRIVILEGES;" > ${BASE_DIR}/mysql/initdb/setup.sql
fi
if ! file_exists ${BASE_DIR}/mysql/logs/error.log; then
chown 999:999 ${BASE_DIR}/mysql/logs;
fi
if [ "$UPDATE" == "true" ]; then
echo "copying $MYSQL_DATABASE database mysql files"
cp -rf ${BASE_DIR}/CommunityServer/mysql/. ${BASE_DIR}/mysql/data
MOVE_COMMUNITY_SERVER_DATABASE="true";
fi
args=();
args+=(--name "$MYSQL_CONTAINER_NAME");
if [ "${USE_AS_EXTERNAL_SERVER}" == "true" ]; then
args+=(-p 3306:3306);
fi
args+=(-v "$BASE_DIR/mysql/conf.d:/etc/mysql/conf.d");
args+=(-v "$BASE_DIR/mysql/data:/var/lib/mysql");
args+=(-v "$BASE_DIR/mysql/initdb:/docker-entrypoint-initdb.d");
args+=(-v "$BASE_DIR/mysql/logs:/var/log/mysql");
args+=(-e "MYSQL_ROOT_PASSWORD=$MYSQL_ROOT_PASSWORD");
args+=(-e "MYSQL_DATABASE=$MYSQL_DATABASE");
args+=("$MYSQL_IMAGE_NAME:$MYSQL_VERSION");
docker run --net ${NETWORK} -i -t -d --restart=always "${args[@]}";
MYSQL_SERVER_ID=$(get_container_id "$MYSQL_CONTAINER_NAME");
if [[ -z ${MYSQL_SERVER_ID} ]]; then
echo "ONLYOFFICE MYSQL SERVER not installed."
exit 1;
fi
if [ "$UPDATE" == "true" ]; then
change_mysql_credentials
fi
fi
}
install_document_server () {
DOCUMENT_SERVER_ID=$(get_container_id "$DOCUMENT_CONTAINER_NAME");
RUN_DOCUMENT_SERVER="true";
if [[ -n ${DOCUMENT_SERVER_ID} ]]; then
if [ "$UPDATE" == "true" ]; then
CURRENT_IMAGE_NAME=$(get_current_image_name "$DOCUMENT_CONTAINER_NAME");
CURRENT_IMAGE_VERSION=$(get_current_image_version "$DOCUMENT_CONTAINER_NAME");
if [ "$CURRENT_IMAGE_NAME" == "onlyoffice/documentserver" ]; then
ACTIVATE_COMMUNITY_SERVER_TRIAL="true";
fi
if [ "$CURRENT_IMAGE_NAME" != "$DOCUMENT_IMAGE_NAME" ] || ([ "$CURRENT_IMAGE_VERSION" != "$DOCUMENT_VERSION" ] || [ "$SKIP_VERSION_CHECK" == "true" ]); then
check_bindings $DOCUMENT_SERVER_ID "/etc/$PRODUCT,/var/lib/$PRODUCT,/var/lib/postgresql,/usr/share/fonts/truetype/custom,/var/lib/rabbitmq,/var/lib/redis";
docker exec ${DOCUMENT_CONTAINER_NAME} bash /usr/bin/documentserver-prepare4shutdown.sh
remove_container ${DOCUMENT_CONTAINER_NAME}
else
RUN_DOCUMENT_SERVER="false";
echo "The latest version of ONLYOFFICE DOCUMENT SERVER is already installed."
docker start ${DOCUMENT_SERVER_ID};
fi
else
RUN_DOCUMENT_SERVER="false";
echo "ONLYOFFICE DOCUMENT SERVER is already installed."
docker start ${DOCUMENT_SERVER_ID};
fi
else
RESTART_COMMUNITY_SERVER="true";
fi
if [ "$RUN_DOCUMENT_SERVER" == "true" ]; then
args=();
args+=(--name "$DOCUMENT_CONTAINER_NAME");
if [ "${USE_AS_EXTERNAL_SERVER}" == "true" ]; then
args+=(-p 80:80);
args+=(-p 443:443);
fi
if [[ -n ${JWT_SECRET} ]]; then
args+=(-e "JWT_ENABLED=$JWT_ENABLED");
args+=(-e "JWT_HEADER=$JWT_HEADER");
args+=(-e "JWT_SECRET=$JWT_SECRET");
else
args+=(-e "JWT_ENABLED=false");
fi
args+=(-v "$BASE_DIR/DocumentServer/data:/var/www/$PRODUCT/Data");
args+=(-v "$BASE_DIR/DocumentServer/logs:/var/log/$PRODUCT");
args+=(-v "$BASE_DIR/DocumentServer/fonts:/usr/share/fonts/truetype/custom");
args+=(-v "$BASE_DIR/DocumentServer/forgotten:/var/lib/$PRODUCT/documentserver/App_Data/cache/files/forgotten");
args+=("$DOCUMENT_IMAGE_NAME:$DOCUMENT_VERSION");
docker run --net ${NETWORK} -i -t -d --restart=always "${args[@]}";
DOCUMENT_SERVER_ID=$(get_container_id "$DOCUMENT_CONTAINER_NAME");
if [[ -z ${DOCUMENT_SERVER_ID} ]]; then
echo "ONLYOFFICE DOCUMENT SERVER not installed."
exit 1;
else
COMMUNITY_SERVER_ID=$(get_container_id "$COMMUNITY_CONTAINER_NAME");
if [[ -n ${COMMUNITY_SERVER_ID} ]]; then
docker exec ${COMMUNITY_CONTAINER_NAME} chown -R ${PRODUCT}:${PRODUCT} /var/www/${PRODUCT}/DocumentServerData
fi
fi
fi
}
install_mail_server () {
MAIL_SERVER_ID=$(get_container_id "$MAIL_CONTAINER_NAME");
MYSQL_SERVER_ID=$(get_container_id "$MYSQL_CONTAINER_NAME");
HOSTNAME_IPS=$(hostname -i);
IP_V4_REGEX="([0-9]{1,3}\.){3}[0-9]{1,3}";
RUN_MAIL_SERVER="true";
if [[ -n ${MAIL_SERVER_ID} ]]; then
if [ "$UPDATE" == "true" ]; then
CURRENT_IMAGE_NAME=$(get_current_image_name "$MAIL_CONTAINER_NAME");
CURRENT_IMAGE_VERSION=$(get_current_image_version "$MAIL_CONTAINER_NAME");
MOVE_DATABASE="false";
if [[ -z ${MYSQL_HOST} ]] && [[ -n ${MYSQL_SERVER_ID} ]]; then
EXIST_DATABASE=$(docker exec -i ${MYSQL_CONTAINER_NAME} mysql -s -N -u ${MYSQL_ROOT_USER} -p${MYSQL_ROOT_PASSWORD} -e "show databases;" 2>/dev/null | { grep -sw ${MYSQL_MAIL_DATABASE} || true; });
if [[ -z ${EXIST_DATABASE} ]]; then
MOVE_DATABASE="true";
fi
fi
if [ "$CURRENT_IMAGE_NAME" != "$MAIL_IMAGE_NAME" ] || ([ "$CURRENT_IMAGE_VERSION" != "$MAIL_VERSION" ] || [ "$SKIP_VERSION_CHECK" == "true" ]) || [ "$MOVE_DATABASE" == "true" ]; then
check_bindings $MAIL_SERVER_ID "/var/lib/mysql";
MAIL_DOMAIN_NAME=$(docker exec $MAIL_SERVER_ID hostname -f);
if [ "$MOVE_DATABASE" == "true" ]; then
move_mail_server_database
fi
stop_mail_server_mysql
remove_container ${MAIL_CONTAINER_NAME}
else
RUN_MAIL_SERVER="false";
echo "The latest version of ONLYOFFICE MAIL SERVER is already installed."
docker start ${MAIL_SERVER_ID};
fi
else
RUN_MAIL_SERVER="false";
echo "ONLYOFFICE MAIL SERVER is already installed."
docker start ${MAIL_SERVER_ID};
fi
else
RESTART_COMMUNITY_SERVER="true";
fi
if [ "$RUN_MAIL_SERVER" == "true" ]; then
if [[ -n ${MAIL_DOMAIN_NAME} ]]; then
args=();
args+=(--name "$MAIL_CONTAINER_NAME");
args+=(-p 25:25);
args+=(-p 143:143);
args+=(-p 587:587);
args+=(-p 465:465);
args+=(-p 993:993);
args+=(-p 995:995);
args+=(-p 4190:4190);
MAIL_SERVER_ADDITIONAL_PORTS="";
if [ "${USE_AS_EXTERNAL_SERVER}" == "true" ]; then
args+=(-p 8081:8081);
if [[ -z ${MYSQL_SERVER_ID} ]]; then
args+=(-p 3306:3306);
fi
for ip in ${HOSTNAME_IPS}
do
if [[ $ip =~ $IP_V4_REGEX ]]; then
args+=(--add-host="$MAIL_DOMAIN_NAME:$ip");
fi
done
fi
MYSQL_SERVER="";
if [[ -n ${MYSQL_SERVER_ID} ]]; then
MYSQL_SERVER="$MYSQL_CONTAINER_NAME";
elif [[ -n ${MYSQL_HOST} ]]; then
MYSQL_SERVER="$MYSQL_HOST";
fi
if [[ -n ${MYSQL_SERVER} ]]; then
args+=(-e "MYSQL_SERVER=$MYSQL_SERVER");
args+=(-e "MYSQL_SERVER_PORT=$MYSQL_PORT");
args+=(-e "MYSQL_ROOT_USER=$MYSQL_ROOT_USER");
args+=(-e "MYSQL_ROOT_PASSWD=$MYSQL_ROOT_PASSWORD");
args+=(-e "MYSQL_SERVER_DB_NAME=$MYSQL_MAIL_DATABASE");
fi
args+=(-v "$BASE_DIR/MailServer/data:/var/vmail");
args+=(-v "$BASE_DIR/MailServer/data/certs:/etc/pki/tls/mailserver");
args+=(-v "$BASE_DIR/MailServer/logs:/var/log");
args+=(-h "$MAIL_DOMAIN_NAME");
args+=("$MAIL_IMAGE_NAME:$MAIL_VERSION");
MAJOR_DOCKER_VERSION=$(docker -v | cut -d ' ' -f3 | cut -d ',' -f1 | cut -d '-' -f1 | cut -d '.' -f1);
if [ ${MAJOR_DOCKER_VERSION} -ge 17 ]; then
docker run --init --net ${NETWORK} --privileged -i -t -d --restart=always "${args[@]}";
else
docker run --net ${NETWORK} --privileged -i -t -d --restart=always "${args[@]}";
fi
MAIL_SERVER_ID=$(get_container_id "$MAIL_CONTAINER_NAME");
if [[ -z ${MAIL_SERVER_ID} ]]; then
echo "ONLYOFFICE MAIL SERVER not installed."
exit 1;
fi
else
echo "mail domain is not specified."
fi
fi
}
install_elasticsearch () {
ELASTICSEARCH_ID=$(get_container_id "$ELASTICSEARCH_CONTAINER_NAME");
RUN_ELASTICSEARCH="true";
if [[ -n ${ELASTICSEARCH_ID} ]]; then
ELASTICSEARCH_SERVER="$ELASTICSEARCH_CONTAINER_NAME";
if [ "$UPDATE" == "true" ]; then
CURRENT_IMAGE_NAME=$(get_current_image_name "$ELASTICSEARCH_CONTAINER_NAME");
CURRENT_IMAGE_VERSION=$(get_current_image_version "$ELASTICSEARCH_CONTAINER_NAME");
if [ "$CURRENT_IMAGE_NAME" != "$ELASTICSEARCH_IMAGE_NAME" ] || \
[ "$CURRENT_IMAGE_VERSION" != "$ELASTICSEARCH_VERSION" ] || \
[ "$SKIP_VERSION_CHECK" == "true" ]; then
check_bindings $ELASTICSEARCH_ID "/usr/share/elasticsearch/data";
remove_container ${ELASTICSEARCH_CONTAINER_NAME}
else
RUN_ELASTICSEARCH="false";
echo "The latest version of ELASTICSEARCH is already installed."
docker start ${ELASTICSEARCH_ID};
fi
else
RUN_ELASTICSEARCH="false";
echo "ELASTICSEARCH is already installed."
docker start ${ELASTICSEARCH_ID};
fi
else
RESTART_COMMUNITY_SERVER="true";
fi
if [ "$RUN_ELASTICSEARCH" == "true" ]; then
args=();
args+=(--name "$ELASTICSEARCH_CONTAINER_NAME");
args+=(-e "discovery.type=single-node");
args+=(-e "bootstrap.memory_lock=true");
args+=(-e "ingest.geoip.downloader.enabled=false");
MEMORY_REQUIREMENTS=12228; #RAM ~12Gb
if [ ${TOTAL_MEMORY} -gt ${MEMORY_REQUIREMENTS} ]; then
args+=(-e "ES_JAVA_OPTS=-Xms4g -Xmx4g -Dlog4j2.formatMsgNoLookups=true");
else
args+=(-e "ES_JAVA_OPTS=-Xms1g -Xmx1g -Dlog4j2.formatMsgNoLookups=true");
fi
args+=(-e "indices.fielddata.cache.size=30%");
args+=(-e "indices.memory.index_buffer_size=30%");
args+=(--ulimit "nofile=65535:65535");
args+=(--ulimit "memlock=-1:-1");
if [ "${USE_AS_EXTERNAL_SERVER}" == "true" ]; then
args+=(-p 9200:9200);
args+=(-p 9300:9300);
fi
args+=(-v "$BASE_DIR/elasticsearch/data:/usr/share/elasticsearch/data");
args+=("$ELASTICSEARCH_IMAGE_NAME:$ELASTICSEARCH_VERSION");
docker run --net ${NETWORK} -i -t -d --restart=always "${args[@]}";
chown -R 1000:1000 $BASE_DIR/elasticsearch #fix AccessDeniedException[/usr/share/elasticsearch/data/nodes]
ELASTICSEARCH_ID=$(get_container_id "$ELASTICSEARCH_CONTAINER_NAME");
if [[ -n ${ELASTICSEARCH_ID} ]]; then
ELASTICSEARCH_SERVER="$ELASTICSEARCH_CONTAINER_NAME";
elif [[ -z ${ELASTICSEARCH_ID} ]]; then
echo "ELASTICSEARCH not installed."
exit 1;
fi
fi
}
install_controlpanel () {
CONTROL_PANEL_ID=$(get_container_id "$CONTROLPANEL_CONTAINER_NAME");
RUN_CONTROL_PANEL="true";
if [[ -n ${CONTROL_PANEL_ID} ]]; then
if [ "$UPDATE" == "true" ]; then
CURRENT_IMAGE_NAME=$(get_current_image_name "$CONTROLPANEL_CONTAINER_NAME");
CURRENT_IMAGE_VERSION=$(get_current_image_version "$CONTROLPANEL_CONTAINER_NAME");
if [ "$CURRENT_IMAGE_NAME" != "$CONTROLPANEL_IMAGE_NAME" ] || ([ "$CURRENT_IMAGE_VERSION" != "$CONTROLPANEL_VERSION" ] || [ "$SKIP_VERSION_CHECK" == "true" ]); then
check_bindings $CONTROL_PANEL_ID "/var/lib/mysql";
remove_container ${CONTROLPANEL_CONTAINER_NAME}
else
RUN_CONTROL_PANEL="false";
echo "The latest version of ONLYOFFICE CONTROL PANEL is already installed."
docker start ${CONTROL_PANEL_ID};
fi
else
RUN_CONTROL_PANEL="false";
echo "ONLYOFFICE CONTROL PANEL is already installed."
docker start ${CONTROL_PANEL_ID};
fi
else
RESTART_COMMUNITY_SERVER="true";
fi
if [ "$RUN_CONTROL_PANEL" == "true" ]; then
args=();
args+=(--name "$CONTROLPANEL_CONTAINER_NAME");
if [[ -n ${MAIL_SERVER_API_HOST} ]]; then
args+=(-e "MAIL_SERVER_EXTERNAL=true");
fi
if [[ -n ${DOCUMENT_SERVER_HOST} ]]; then
args+=(-e "DOCUMENT_SERVER_EXTERNAL=true");
fi
if [[ -n ${COMMUNITY_SERVER_HOST} ]]; then
args+=(-e "COMMUNITY_SERVER_EXTERNAL=true");
fi
if [[ -n ${CORE_MACHINEKEY} ]]; then
args+=(-e "$MACHINEKEY_PARAM=$CORE_MACHINEKEY");
fi
args+=(-v "/var/run/docker.sock:/var/run/docker.sock");
args+=(-v "$BASE_DIR/CommunityServer/data:/app/$PRODUCT/CommunityServer/data");
args+=(-v "$BASE_DIR/ControlPanel/data:/var/www/$PRODUCT/Data");
args+=(-v "$BASE_DIR/ControlPanel/logs:/var/log/$PRODUCT");
args+=("$CONTROLPANEL_IMAGE_NAME:$CONTROLPANEL_VERSION");
docker run --net ${NETWORK} -i -t -d --restart=always "${args[@]}";
CONTROL_PANEL_ID=$(get_container_id "$CONTROLPANEL_CONTAINER_NAME");
if [[ -z ${CONTROL_PANEL_ID} ]]; then
echo "ONLYOFFICE CONTROL PANEL not installed."
exit 1;
fi
fi
}
install_community_server () {
COMMUNITY_SERVER_ID=$(get_container_id "$COMMUNITY_CONTAINER_NAME");
DOCUMENT_SERVER_ID=$(get_container_id "$DOCUMENT_CONTAINER_NAME");
MAIL_SERVER_ID=$(get_container_id "$MAIL_CONTAINER_NAME");
CONTROL_PANEL_ID=$(get_container_id "$CONTROLPANEL_CONTAINER_NAME");
MYSQL_SERVER_ID=$(get_container_id "$MYSQL_CONTAINER_NAME");
RUN_COMMUNITY_SERVER="true";
if [[ -n ${COMMUNITY_SERVER_ID} ]]; then
docker exec -d ${COMMUNITY_CONTAINER_NAME} bash -c "cp -rf /var/www/${PRODUCT}/WebStudio/App_Data/static/partnerdata /var/www/${PRODUCT}/Data/"
if [ "$UPDATE" == "true" ]; then
CURRENT_IMAGE_NAME=$(get_current_image_name "$COMMUNITY_CONTAINER_NAME");
CURRENT_IMAGE_VERSION=$(get_current_image_version "$COMMUNITY_CONTAINER_NAME");
if [ "$CURRENT_IMAGE_NAME" != "$COMMUNITY_IMAGE_NAME" ] || ([ "$CURRENT_IMAGE_VERSION" != "$COMMUNITY_VERSION" ] || [ "$SKIP_VERSION_CHECK" == "true" ]) || [ "$MOVE_COMMUNITY_SERVER_DATABASE" == "true" ]; then
check_bindings $COMMUNITY_SERVER_ID "/var/lib/mysql";
COMMUNITY_PORT=$(docker port $COMMUNITY_SERVER_ID 80 | sed 's/.*://' | head -n1)
stop_community_server_mysql
remove_container ${COMMUNITY_CONTAINER_NAME}
else
RUN_COMMUNITY_SERVER="false";
if [ "$ACTIVATE_COMMUNITY_SERVER_TRIAL" == "true" ]; then
docker restart ${COMMUNITY_CONTAINER_NAME}
fi
echo "The latest version of ONLYOFFICE COMMUNITY SERVER is already installed."
docker start ${COMMUNITY_SERVER_ID};
fi
else
if [ "$RESTART_COMMUNITY_SERVER" == "true" ]; then
check_bindings $COMMUNITY_SERVER_ID "/var/lib/mysql";
COMMUNITY_PORT=$(docker port $COMMUNITY_SERVER_ID 80 | sed 's/.*://' | head -n1)
stop_community_server_mysql
remove_container ${COMMUNITY_CONTAINER_NAME}
else
RUN_COMMUNITY_SERVER="false";
echo "ONLYOFFICE COMMUNITY SERVER is already installed."
docker start ${COMMUNITY_SERVER_ID};
fi
fi
fi
if [ "$RUN_COMMUNITY_SERVER" == "true" ]; then
args=();
args+=(--name "$COMMUNITY_CONTAINER_NAME");
args+=(-p "$COMMUNITY_PORT:80");
args+=(-p 443:443);
args+=(-p 5222:5222);
args+=(--cgroupns host);
if [[ -n ${MAIL_SERVER_API_HOST} ]]; then
args+=(-e "MAIL_SERVER_API_HOST=$MAIL_SERVER_API_HOST");
if [[ -n ${MAIL_SERVER_DB_HOST} ]]; then
args+=(-e "MAIL_SERVER_DB_HOST=$MAIL_SERVER_DB_HOST");
else
args+=(-e "MAIL_SERVER_DB_HOST=$MAIL_SERVER_API_HOST");
fi
fi
if [[ -n ${MAIL_DOMAIN_NAME} ]]; then
args+=(-e "MAIL_DOMAIN_NAME=$MAIL_DOMAIN_NAME");
fi
if [[ -n ${DOCUMENT_SERVER_HOST} ]]; then
args+=(-e "DOCUMENT_SERVER_HOST=$DOCUMENT_SERVER_HOST");
fi
if [[ -n ${DOCUMENT_SERVER_ID} ]]; then
args+=(-e "DOCUMENT_SERVER_PORT_80_TCP_ADDR=$DOCUMENT_CONTAINER_NAME");
fi
MYSQL_SERVER="";
if [[ -n ${MYSQL_SERVER_ID} ]]; then
MYSQL_SERVER="$MYSQL_CONTAINER_NAME";
elif [[ -n ${MYSQL_HOST} ]]; then
MYSQL_SERVER="$MYSQL_HOST";
fi
if [[ -n ${MYSQL_SERVER} ]]; then
args+=(-e "MYSQL_SERVER_ROOT_PASSWORD=$MYSQL_ROOT_PASSWORD");
args+=(-e "MYSQL_SERVER_DB_NAME=$MYSQL_DATABASE");
args+=(-e "MYSQL_SERVER_HOST=$MYSQL_SERVER");
args+=(-e "MYSQL_SERVER_USER=$MYSQL_USER");
args+=(-e "MYSQL_SERVER_PASS=$MYSQL_PASSWORD");
fi
if [[ -n ${ELASTICSEARCH_SERVER} ]]; then
args+=(-e "ELASTICSEARCH_SERVER_HOST=$ELASTICSEARCH_SERVER");
args+=(-e "ELASTICSEARCH_SERVER_HTTPPORT=$ELASTICSEARCH_PORT");
fi
if [[ -n ${MAIL_SERVER_ID} ]]; then
args+=(-e "MAIL_SERVER_API_HOST=$MAIL_CONTAINER_NAME");
if [[ -n ${MYSQL_SERVER} ]]; then
args+=(-e "MAIL_SERVER_DB_HOST=$MYSQL_SERVER");
args+=(-e "MAIL_SERVER_DB_NAME=$MYSQL_MAIL_DATABASE");
args+=(-e "MAIL_SERVER_DB_PORT=$MYSQL_PORT");
args+=(-e "MAIL_SERVER_DB_USER=$MYSQL_ROOT_USER");
args+=(-e "MAIL_SERVER_DB_PASS=$MYSQL_ROOT_PASSWORD");
else
args+=(-e "MAIL_SERVER_DB_HOST=$MAIL_CONTAINER_NAME");
fi
fi
if [[ -n ${MAIL_IMAPSYNC_START_DATE} ]]; then
args+=(-e "MAIL_IMAPSYNC_START_DATE=$MAIL_IMAPSYNC_START_DATE");
fi
if [[ -n ${CONTROL_PANEL_ID} ]]; then
args+=(-e "CONTROL_PANEL_PORT_80_TCP=80");
args+=(-e "CONTROL_PANEL_PORT_80_TCP_ADDR=$CONTROLPANEL_CONTAINER_NAME");
fi
if [[ -n ${JWT_SECRET} ]]; then
args+=(-e "DOCUMENT_SERVER_JWT_ENABLED=$JWT_ENABLED");
args+=(-e "DOCUMENT_SERVER_JWT_HEADER=$JWT_HEADER");
args+=(-e "DOCUMENT_SERVER_JWT_SECRET=$JWT_SECRET");
else
args+=(-e "DOCUMENT_SERVER_JWT_ENABLED=false");
fi
if [[ -n ${CORE_MACHINEKEY} ]]; then
args+=(-e "$MACHINEKEY_PARAM=$CORE_MACHINEKEY");
fi
args+=(-v "$BASE_DIR/CommunityServer/letsencrypt:/etc/letsencrypt");
args+=(-v "/sys/fs/cgroup:/sys/fs/cgroup:rw");
args+=(-v "$BASE_DIR/CommunityServer/data:/var/www/$PRODUCT/Data");
args+=(-v "$BASE_DIR/CommunityServer/logs:/var/log/$PRODUCT");
args+=(-v "$BASE_DIR/DocumentServer/data:/var/www/$PRODUCT/DocumentServerData");
args+=("$COMMUNITY_IMAGE_NAME:$COMMUNITY_VERSION");
docker run --net ${NETWORK} -itd --privileged --restart=always "${args[@]}";
COMMUNITY_SERVER_ID=$(get_container_id "$COMMUNITY_CONTAINER_NAME");
if [[ -z ${COMMUNITY_SERVER_ID} ]]; then
echo "ONLYOFFICE COMMUNITY SERVER not installed."
exit 1;
else
docker exec -d ${COMMUNITY_CONTAINER_NAME} bash -c "[ -d /var/www/${PRODUCT}/Data/partnerdata ] && cp /var/www/${PRODUCT}/Data/partnerdata/* /var/www/${PRODUCT}/WebStudio/App_Data/static/partnerdata/ && rm -rf /var/www/${PRODUCT}/Data/partnerdata"
fi
fi
}
get_container_id () {
CONTAINER_NAME=$1;
if [[ -z ${CONTAINER_NAME} ]]; then
echo "Empty container name"
exit 1;
fi
CONTAINER_ID="";
CONTAINER_EXIST=$(docker ps -aqf "name=$CONTAINER_NAME");
if [[ -n ${CONTAINER_EXIST} ]]; then
CONTAINER_ID=$(docker inspect --format='{{.Id}}' ${CONTAINER_NAME});
fi
echo "$CONTAINER_ID"
}
get_container_ip () {
CONTAINER_NAME=$1;
if [[ -z ${CONTAINER_NAME} ]]; then
echo "Empty container name"
exit 1;
fi
CONTAINER_IP="";
CONTAINER_EXIST=$(docker ps -aqf "name=$CONTAINER_NAME");
if [[ -n ${CONTAINER_EXIST} ]]; then
CONTAINER_IP=$(docker inspect -f '{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' ${CONTAINER_NAME});
fi
echo "$CONTAINER_IP"
}
get_random_str () {
LENGTH=$1;
if [[ -z ${LENGTH} ]]; then
LENGTH=12;
fi
VALUE=$(cat /dev/urandom | tr -dc A-Za-z0-9 | head -c ${LENGTH});
echo "$VALUE"
}
set_jwt_secret () {
CURRENT_JWT_SECRET="";
if [[ -z ${JWT_SECRET} ]]; then
CURRENT_JWT_SECRET=$(get_container_env_parameter "$DOCUMENT_CONTAINER_NAME" "JWT_SECRET");
if [[ -n ${CURRENT_JWT_SECRET} ]]; then
JWT_SECRET="$CURRENT_JWT_SECRET";
fi
fi
if [[ -z ${JWT_SECRET} ]]; then
CURRENT_JWT_SECRET=$(get_container_env_parameter "$COMMUNITY_CONTAINER_NAME" "DOCUMENT_SERVER_JWT_SECRET");
if [[ -n ${CURRENT_JWT_SECRET} ]]; then
JWT_SECRET="$CURRENT_JWT_SECRET";
fi
fi
if [[ -z ${JWT_SECRET} ]] && [[ "$USE_AS_EXTERNAL_SERVER" != "true" ]]; then
JWT_SECRET=$(get_random_str 32);
[ $JWT_ENABLED = "true" ] && JWT_MESSAGE='JWT is enabled by default. A random secret is generated automatically. Run the command "docker exec $(sudo docker ps -q) sudo documentserver-jwt-status.sh" to get information about JWT.'
fi
}
set_jwt_header () {
CURRENT_JWT_HEADER="";
if [[ -z ${JWT_HEADER} ]]; then
CURRENT_JWT_HEADER=$(get_container_env_parameter "$DOCUMENT_CONTAINER_NAME" "JWT_HEADER");
if [[ -n ${CURRENT_JWT_HEADER} ]]; then
JWT_HEADER="$CURRENT_JWT_HEADER";
fi
fi
if [[ -z ${JWT_HEADER} ]]; then
CURRENT_JWT_HEADER=$(get_container_env_parameter "$COMMUNITY_CONTAINER_NAME" "DOCUMENT_SERVER_JWT_HEADER");
if [[ -n ${CURRENT_JWT_HEADER} ]]; then
JWT_HEADER="$CURRENT_JWT_HEADER";
fi
fi
if [[ -z ${JWT_HEADER} ]]; then
JWT_HEADER="AuthorizationJwt"
fi
}
set_jwt_enabled () {
CURRENT_JWT_ENABLED="";
if [[ -z ${JWT_ENABLED} ]]; then
CURRENT_JWT_ENABLED=$(get_container_env_parameter "$DOCUMENT_CONTAINER_NAME" "JWT_ENABLED");
if [[ -n ${CURRENT_JWT_ENABLED} ]]; then
JWT_ENABLED="$CURRENT_JWT_ENABLED";
fi
fi
if [[ -z ${JWT_ENABLED} ]]; then
CURRENT_JWT_ENABLED=$(get_container_env_parameter "$COMMUNITY_CONTAINER_NAME" "DOCUMENT_SERVER_JWT_ENABLED");
if [[ -n ${CURRENT_JWT_ENABLED} ]]; then
JWT_ENABLED="$CURRENT_JWT_ENABLED";
fi
fi
if [[ -z ${JWT_ENABLED} ]]; then
JWT_ENABLED="true"
fi
}
set_core_machinekey () {
CURRENT_CORE_MACHINEKEY="";
if [[ -z ${CORE_MACHINEKEY} ]]; then
if file_exists ${BASE_DIR}/CommunityServer/data/.private/machinekey; then
CURRENT_CORE_MACHINEKEY=$(cat ${BASE_DIR}/CommunityServer/data/.private/machinekey);
if [[ -n ${CURRENT_CORE_MACHINEKEY} ]]; then
CORE_MACHINEKEY="$CURRENT_CORE_MACHINEKEY";
fi
fi
fi
if [[ -z ${CORE_MACHINEKEY} ]]; then
CURRENT_CORE_MACHINEKEY=$(get_container_env_parameter "$CONTROLPANEL_CONTAINER_NAME" "$MACHINEKEY_PARAM");
if [[ -n ${CURRENT_CORE_MACHINEKEY} ]]; then
CORE_MACHINEKEY="$CURRENT_CORE_MACHINEKEY";
fi
fi
if [[ -z ${CORE_MACHINEKEY} ]]; then
CURRENT_CORE_MACHINEKEY=$(get_container_env_parameter "$COMMUNITY_CONTAINER_NAME" "$MACHINEKEY_PARAM");
if [[ -n ${CURRENT_CORE_MACHINEKEY} ]]; then
CORE_MACHINEKEY="$CURRENT_CORE_MACHINEKEY";
fi
fi
if [[ -z ${CORE_MACHINEKEY} ]] && [[ "$UPDATE" != "true" ]] && [[ "$USE_AS_EXTERNAL_SERVER" != "true" ]]; then
CORE_MACHINEKEY=$(get_random_str 12);
fi
}
read_parameters () {
COMMUNITY_SERVER_ID=$(get_container_id "$COMMUNITY_CONTAINER_NAME");
MAIL_SERVER_ID=$(get_container_id "$MAIL_CONTAINER_NAME");
PARAMETER_VALUE="";
if [[ -n ${COMMUNITY_SERVER_ID} ]]; then
PARAMETER_VALUE=$(get_container_env_parameter "$COMMUNITY_CONTAINER_NAME" "MYSQL_SERVER_HOST");
if [[ -n ${PARAMETER_VALUE} ]]; then
MYSQL_HOST="$PARAMETER_VALUE";
if [ "$MYSQL_HOST" == "$MYSQL_CONTAINER_NAME" ]; then
MYSQL_HOST="";
fi
fi
PARAMETER_VALUE=$(get_container_env_parameter "$COMMUNITY_CONTAINER_NAME" "MYSQL_SERVER_ROOT_PASSWORD");
if [[ -n ${PARAMETER_VALUE} ]]; then
MYSQL_ROOT_PASSWORD="$PARAMETER_VALUE";
fi
PARAMETER_VALUE=$(get_container_env_parameter "$COMMUNITY_CONTAINER_NAME" "MYSQL_SERVER_DB_NAME");
if [[ -n ${PARAMETER_VALUE} ]]; then
MYSQL_DATABASE="$PARAMETER_VALUE";
fi
PARAMETER_VALUE=$(get_container_env_parameter "$COMMUNITY_CONTAINER_NAME" "MYSQL_SERVER_USER");
if [[ -n ${PARAMETER_VALUE} ]]; then
MYSQL_USER="$PARAMETER_VALUE";
fi
PARAMETER_VALUE=$(get_container_env_parameter "$COMMUNITY_CONTAINER_NAME" "MYSQL_SERVER_PASS");
if [[ -n ${PARAMETER_VALUE} ]]; then
MYSQL_PASSWORD="$PARAMETER_VALUE";
fi
PARAMETER_VALUE=$(get_container_env_parameter "$COMMUNITY_CONTAINER_NAME" "ELASTICSEARCH_SERVER_HOST");
if [[ -n ${PARAMETER_VALUE} ]]; then
ELASTICSEARCH_HOST="$PARAMETER_VALUE";
if [ "$ELASTICSEARCH_HOST" == "$ELASTICSEARCH_CONTAINER_NAME" ]; then
ELASTICSEARCH_HOST="";
fi
fi
PARAMETER_VALUE=$(get_container_env_parameter "$COMMUNITY_CONTAINER_NAME" "ELASTICSEARCH_SERVER_HTTPPORT");
if [[ -n ${PARAMETER_VALUE} ]]; then
ELASTICSEARCH_PORT="$PARAMETER_VALUE";
fi
PARAMETER_VALUE=$(get_container_env_parameter "$COMMUNITY_CONTAINER_NAME" "MAIL_IMAPSYNC_START_DATE");
if [[ -n ${PARAMETER_VALUE} ]]; then
MAIL_IMAPSYNC_START_DATE="$PARAMETER_VALUE";
fi
fi
if [[ -n ${MAIL_SERVER_ID} ]]; then
PARAMETER_VALUE=$(get_container_env_parameter "$MAIL_CONTAINER_NAME" "MYSQL_SERVER");
if [[ -n ${PARAMETER_VALUE} ]]; then
MYSQL_HOST="$PARAMETER_VALUE";
if [ "$MYSQL_HOST" == "$MYSQL_CONTAINER_NAME" ]; then
MYSQL_HOST="";
fi
fi
PARAMETER_VALUE=$(get_container_env_parameter "$MAIL_CONTAINER_NAME" "MYSQL_SERVER_PORT");
if [[ -n ${PARAMETER_VALUE} ]]; then
MYSQL_PORT="$PARAMETER_VALUE";
fi
PARAMETER_VALUE=$(get_container_env_parameter "$MAIL_CONTAINER_NAME" "MYSQL_ROOT_USER");
if [[ -n ${PARAMETER_VALUE} ]]; then
MYSQL_ROOT_USER="$PARAMETER_VALUE";
fi
PARAMETER_VALUE=$(get_container_env_parameter "$MAIL_CONTAINER_NAME" "MYSQL_ROOT_PASSWD");
if [[ -n ${PARAMETER_VALUE} ]]; then
MYSQL_ROOT_PASSWORD="$PARAMETER_VALUE";
fi
PARAMETER_VALUE=$(get_container_env_parameter "$MAIL_CONTAINER_NAME" "MYSQL_SERVER_DB_NAME");
if [[ -n ${PARAMETER_VALUE} ]]; then
MYSQL_MAIL_DATABASE="$PARAMETER_VALUE";
fi
fi
}
get_container_env_parameter () {
CONTAINER_NAME=$1;
PARAMETER_NAME=$2;
VALUE="";
if [[ -z ${CONTAINER_NAME} ]]; then
echo "Empty container name"
exit 1;
fi
if [[ -z ${PARAMETER_NAME} ]]; then
echo "Empty parameter name"
exit 1;
fi
if command_exists docker ; then
CONTAINER_EXIST=$(docker ps -aqf "name=$CONTAINER_NAME");
if [[ -n ${CONTAINER_EXIST} ]]; then
VALUE=$(docker inspect --format='{{range .Config.Env}}{{println .}}{{end}}' ${CONTAINER_NAME} | grep "${PARAMETER_NAME}=" | sed 's/^.*=//');
fi
fi
echo "$VALUE"
}
move_mail_server_database () {
EXIST_DATABASE=$(docker exec -i ${MYSQL_CONTAINER_NAME} mysql -s -N -u ${MYSQL_ROOT_USER} -p${MYSQL_ROOT_PASSWORD} -e "show databases;" 2>/dev/null | { grep -sw ${MYSQL_MAIL_DATABASE} || true; });
EXIST_MAIL_DATABASE=$(docker exec -itd ${MAIL_CONTAINER_NAME} mysql -s -N -u ${MYSQL_ROOT_USER} -p${MYSQL_MAIL_ROOT_PASSWORD} -e "show databases;" 2>/dev/null | { grep -sw ${MYSQL_MAIL_DATABASE} || true; })
if [[ -n ${EXIST_DATABASE} ]]; then
echo "$MYSQL_MAIL_DATABASE database already exist in $MYSQL_CONTAINER_NAME"
elif [[ -z "${EXIST_MAIL_DATABASE}" ]]; then
echo "$MYSQL_MAIL_DATABASE database does not exist in $MAIL_CONTAINER_NAME"
else
if ! docker exec -itd ${MAIL_CONTAINER_NAME} mysqladmin -u ${MYSQL_ROOT_USER} -p${MYSQL_MAIL_ROOT_PASSWORD} status; then
echo "$MAIL_CONTAINER_NAME mysqld service not available."
exit 1;
fi
echo "creating $MYSQL_MAIL_DATABASE database dump file"
if ! docker exec -it ${MAIL_CONTAINER_NAME} mysqldump -u ${MYSQL_ROOT_USER} -p${MYSQL_MAIL_ROOT_PASSWORD} ${MYSQL_MAIL_DATABASE} > dump.sql; then
echo "$MAIL_CONTAINER_NAME could not create $MYSQL_MAIL_DATABASE database dump file"
exit 1;
fi
if ! docker exec -i ${MYSQL_CONTAINER_NAME} mysql -u ${MYSQL_ROOT_USER} -p${MYSQL_ROOT_PASSWORD} -e "CREATE DATABASE \`${MYSQL_MAIL_DATABASE}\`"; then
echo "$MYSQL_CONTAINER_NAME could not create $MYSQL_MAIL_DATABASE database"
exit 1;
fi
echo "restoring $MYSQL_MAIL_DATABASE database dump file"
if ! docker exec -i ${MYSQL_CONTAINER_NAME} mysql -u ${MYSQL_ROOT_USER} -p${MYSQL_ROOT_PASSWORD} ${MYSQL_MAIL_DATABASE} < dump.sql; then
echo "$MYSQL_CONTAINER_NAME could not restore $MYSQL_MAIL_DATABASE database dump file"
exit 1;
fi
rm -f dump.sql
fi
}
stop_mail_server_mysql () {
if ! docker exec -it ${MAIL_CONTAINER_NAME} service mysqld stop; then
echo "$MAIL_CONTAINER_NAME mysqld service could not be stopped correctly."
fi
}
stop_community_server_mysql () {
if ! docker exec -it ${COMMUNITY_CONTAINER_NAME} service god stop; then
echo "$COMMUNITY_CONTAINER_NAME god service could not be stopped correctly."
fi
if ! docker exec -it ${COMMUNITY_CONTAINER_NAME} service mysql stop; then
echo "$COMMUNITY_CONTAINER_NAME mysql service could not be stopped correctly."
fi
}
remove_container () {
CONTAINER_NAME=$1;
if [[ -z ${CONTAINER_NAME} ]]; then
echo "Empty container name"
exit 1;
fi
echo "stop container:"
docker stop ${CONTAINER_NAME};
echo "remove container:"
docker rm -f ${CONTAINER_NAME};
sleep 10 #Hack for SuSe: exception "Error response from daemon: devmapper: Unknown device xxx"
echo "check removed container: $CONTAINER_NAME"
CONTAINER_ID=$(get_container_id "$CONTAINER_NAME");
if [[ -n ${CONTAINER_ID} ]]; then
echo "try again remove ${CONTAINER_NAME}"
remove_container ${CONTAINER_NAME}
fi
}
pull_mysql_server () {
if file_exists ${BASE_DIR}/mysql/.private/$MYSQL_DATABASE.version; then
MYSQL_VERSION=$(cat ${BASE_DIR}/mysql/.private/$MYSQL_DATABASE.version)
elif grep "Version:" ${BASE_DIR}/mysql/logs/error.log > /dev/null 2>&1 ; then
MYSQL_VERSION=$(grep "Version:" ${BASE_DIR}/mysql/logs/error.log | grep -Po "'[0-99].[0-99]..*?'" | head -1 | tr -d \')
fi
echo $MYSQL_VERSION > ${BASE_DIR}/mysql/.private/$MYSQL_DATABASE.version
if file_exists "${MYSQL_IMAGE_NAME}"; then
docker load -i ${MYSQL_IMAGE_NAME}
FILE_NAME=$(basename $MYSQL_IMAGE_NAME)
TMP_STRING=${FILE_NAME//.tar.gz/ }
TMP_ARRAY=(${TMP_STRING//_/ })
MYSQL_IMAGE_NAME=${TMP_ARRAY[0]/-//}
MYSQL_VERSION="${TMP_ARRAY[1]}"
else
if [[ -z ${MYSQL_VERSION} ]]; then
MYSQL_VERSION=$(get_available_version "$MYSQL_IMAGE_NAME");
fi
pull_image ${MYSQL_IMAGE_NAME} ${MYSQL_VERSION}
fi
}
pull_document_server () {
if file_exists "${DOCUMENT_IMAGE_NAME}"; then
docker load -i ${DOCUMENT_IMAGE_NAME}
FILE_NAME=$(basename $DOCUMENT_IMAGE_NAME)
TMP_STRING=${FILE_NAME//.tar.gz/ }
TMP_ARRAY=(${TMP_STRING//-/ })
DOCUMENT_IMAGE_NAME="${TMP_ARRAY[0]}/${TMP_ARRAY[1]}"
DOCUMENT_VERSION="${TMP_ARRAY[2]}"
else
if [[ -z ${DOCUMENT_VERSION} ]]; then
DOCUMENT_VERSION=$(get_available_version "$DOCUMENT_IMAGE_NAME");
fi
pull_image ${DOCUMENT_IMAGE_NAME} ${DOCUMENT_VERSION}
fi
}
pull_mail_server () {
if file_exists "${MAIL_IMAGE_NAME}"; then
docker load -i ${MAIL_IMAGE_NAME}
FILE_NAME=$(basename $MAIL_IMAGE_NAME)
TMP_STRING=${FILE_NAME//.tar.gz/ }
TMP_ARRAY=(${TMP_STRING//-/ })
MAIL_IMAGE_NAME="${TMP_ARRAY[0]}/${TMP_ARRAY[1]}"
MAIL_VERSION="${TMP_ARRAY[2]}"
else
if [[ -z ${MAIL_VERSION} ]]; then
MAIL_VERSION=$(get_available_version "$MAIL_IMAGE_NAME");
fi
pull_image ${MAIL_IMAGE_NAME} ${MAIL_VERSION}
fi
}
pull_elasticsearch () {
if file_exists "${ELASTICSEARCH_IMAGE_NAME}"; then
docker load -i ${ELASTICSEARCH_IMAGE_NAME}
FILE_NAME=$(basename $ELASTICSEARCH_IMAGE_NAME)
TMP_STRING=${FILE_NAME//.tar.gz/ }
TMP_ARRAY=(${TMP_STRING//-/ })
ELASTICSEARCH_IMAGE_NAME="${TMP_ARRAY[0]}/${TMP_ARRAY[1]}"
ELASTICSEARCH_VERSION="${TMP_ARRAY[2]}"
else
if [[ -z ${ELASTICSEARCH_VERSION} ]]; then
ELASTICSEARCH_VERSION=$(get_available_version "$ELASTICSEARCH_IMAGE_NAME");
fi
pull_image ${ELASTICSEARCH_IMAGE_NAME} ${ELASTICSEARCH_VERSION}
fi
}
pull_controlpanel () {
if file_exists "${CONTROLPANEL_IMAGE_NAME}"; then
docker load -i ${CONTROLPANEL_IMAGE_NAME}
FILE_NAME=$(basename $CONTROLPANEL_IMAGE_NAME)
TMP_STRING=${FILE_NAME//.tar.gz/ }
TMP_ARRAY=(${TMP_STRING//-/ })
CONTROLPANEL_IMAGE_NAME="${TMP_ARRAY[0]}/${TMP_ARRAY[1]}"
CONTROLPANEL_VERSION="${TMP_ARRAY[2]}"
else
if [[ -z ${CONTROLPANEL_VERSION} ]]; then
CONTROLPANEL_VERSION=$(get_available_version "$CONTROLPANEL_IMAGE_NAME");
fi
pull_image ${CONTROLPANEL_IMAGE_NAME} ${CONTROLPANEL_VERSION}
fi
}
pull_community_server () {
if file_exists "${COMMUNITY_IMAGE_NAME}"; then
docker load -i ${COMMUNITY_IMAGE_NAME}
FILE_NAME=$(basename $COMMUNITY_IMAGE_NAME)
TMP_STRING=${FILE_NAME//.tar.gz/ }
TMP_ARRAY=(${TMP_STRING//_/ })
COMMUNITY_IMAGE_NAME=${TMP_ARRAY[0]/-//}
COMMUNITY_VERSION="${TMP_ARRAY[1]}"
else
if [[ -z ${COMMUNITY_VERSION} ]]; then
COMMUNITY_VERSION=$(get_available_version "$COMMUNITY_IMAGE_NAME");
fi
pull_image ${COMMUNITY_IMAGE_NAME} ${COMMUNITY_VERSION}
fi
}
pull_image () {
IMAGE_NAME=$1;
IMAGE_VERSION=$2;
if [[ -z ${IMAGE_NAME} || -z ${IMAGE_VERSION} ]]; then
echo "Docker pull argument exception: repository=$IMAGE_NAME, tag=$IMAGE_VERSION"
exit 1;
fi
EXIST=$(docker images | grep "$IMAGE_NAME" | awk '{print $2;}' | { grep -x "$IMAGE_VERSION" || true; });
COUNT=1;
while [[ -z $EXIST && $COUNT -le 3 ]]; do
docker pull ${IMAGE_NAME}:${IMAGE_VERSION}
EXIST=$(docker images | grep "$IMAGE_NAME" | awk '{print $2;}' | { grep -x "$IMAGE_VERSION" || true; });
(( COUNT++ ))
done
if [[ -z $EXIST ]]; then
echo "Docker image $IMAGE_NAME:$IMAGE_VERSION not found"
exit 1;
fi
}
set_partner_data () {
if [[ -n ${PARTNER_DATA_FILE} ]]; then
curl -o ${BASE_DIR}/CommunityServer/data/json-data.txt ${PARTNER_DATA_FILE}
fi
}
create_network () {
EXIST=$(docker network ls | awk '{print $2;}' | { grep -x ${NETWORK} || true; });
if [[ -z ${EXIST} ]]; then
docker network create --driver bridge ${NETWORK}
fi
}
set_installation_type_data () {
if [ "$INSTALLATION_TYPE" == "GROUPS" ]; then
INSTALL_DOCUMENT_SERVER="false";
INSTALL_MAIL_SERVER="false";
set_opensource_data
elif [ "$INSTALLATION_TYPE" == "WORKSPACE" ]; then
set_opensource_data
fi
}
set_opensource_data () {
COMMUNITY_IMAGE_NAME="onlyoffice/communityserver";
DOCUMENT_IMAGE_NAME="onlyoffice/documentserver";
MAIL_IMAGE_NAME="onlyoffice/mailserver";
CONTROLPANEL_IMAGE_NAME="onlyoffice/controlpanel";
HUB="";
USERNAME="";
PASSWORD="";
}
ping_host_port () {
HOST=$1
PORT=$2
if [ -z "$HOST" ] || [ -z "$PORT" ]; then
echo "mysql host or port is empty"
exit 1;
fi
if command_exists nc ; then
RESULT=`nc -z -v -w5 $HOST $PORT &> /dev/null; echo $?`
if [ $RESULT != 0 ]; then
echo "Error ping $HOST:$PORT"
exit 1;
fi
fi
}
check_domain () {
if ! command_exists dig ; then
if command_exists apt-get; then
apt-get -y update
apt-get install -y dnsutils
elif command_exists yum; then
yum install bind-utils
fi
if ! command_exists dig; then
echo "command dig not found"
exit 1;
fi
if ! command_exists host; then
echo "command host not found"
exit 1;
fi
fi
IP=$(dig +short myip.opendns.com @resolver1.opendns.com)
RESULT=$(host $MAIL_DOMAIN_NAME | { grep $IP || true; })
if [[ -z $IP ]]; then
echo "Could not determine the external ip of the current server";
RESULT=true;
elif [[ -z ${RESULT} ]]; then
echo "$MAIL_DOMAIN_NAME is not linked to the $IP address. Please check your A-record."
exit 1;
fi
}
check_vsyscall () {
MIN_NUM_ARR=(4 18 0);
CUR_NUM_ARR=();
CUR_STR_ARR=$(echo $KERNEL | grep -Po "[0-9]+\.[0-9]+\.[0-9]+" | tr "." " ");
for CUR_STR_ITEM in $CUR_STR_ARR
do
CUR_NUM_ARR=(${CUR_NUM_ARR[@]} $CUR_STR_ITEM)
done
INDEX=0;
NEED_VSYSCALL_CHECK="true";
while [[ $INDEX -lt 3 ]]; do
if [ ${CUR_NUM_ARR[INDEX]} -lt ${MIN_NUM_ARR[INDEX]} ]; then
NEED_VSYSCALL_CHECK="false";
INDEX=3;
elif [ ${CUR_NUM_ARR[INDEX]} -gt ${MIN_NUM_ARR[INDEX]} ]; then
INDEX=3;
fi
(( INDEX++ ))
done
if [ "$NEED_VSYSCALL_CHECK" == "true" ]; then
VSYSCALL_ENABLED=$(cat /proc/self/maps | egrep 'vsyscall');
if [ -z "$VSYSCALL_ENABLED" ]; then
echo "vsyscall is required for the Mail Server to work correctly"
echo "Please use this instruction https://helpcenter.onlyoffice.com/server/docker/mail/enabling-vsyscall-on-debian.aspx"
exit 1;
fi
fi
}
start_installation () {
root_checking
set_installation_type_data
set_jwt_enabled
set_jwt_header
set_jwt_secret
set_core_machinekey
if [ "$UPDATE" == "true" ]; then
read_parameters
fi
get_os_info
check_os_info
check_kernel
if [ "$SKIP_HARDWARE_CHECK" != "true" ]; then
check_hardware
fi
if [ "$UPDATE" != "true" ]; then
check_ports
MYSQL_VERSION="8.0.29";
if [ "$INSTALL_MAIL_SERVER" == "true" ]; then
if [[ -z ${MAIL_DOMAIN_NAME} ]]; then
INSTALL_MAIL_SERVER_TEMP="";
while [ "$INSTALL_MAIL_SERVER_TEMP" != "Y" ] && [ "$INSTALL_MAIL_SERVER_TEMP" != "N" ]; do
read -p "Install ONLYOFFICE Mail Server [Y/N]?: " INSTALL_MAIL_SERVER_TEMP
INSTALL_MAIL_SERVER_TEMP="$(echo $INSTALL_MAIL_SERVER_TEMP | tr '[:lower:]' '[:upper:]')";
done
if [ "$INSTALL_MAIL_SERVER_TEMP" = "Y" ]; then
while [ -z "$MAIL_DOMAIN_NAME" ]; do
read -p "Enter mail domain for ONLYOFFICE Mail Server: " MAIL_DOMAIN_NAME
done
fi
fi
if [[ -z ${MAIL_DOMAIN_NAME} ]]; then
INSTALL_MAIL_SERVER="false";
elif [ "$SKIP_DOMAIN_CHECK" != "true" ]; then
check_domain
fi
if [ "$INSTALL_MAIL_SERVER" == "true" ] && [ "$DIST" == "Debian" ]; then
check_vsyscall
fi
fi
elif [[ -z $(get_container_id "$MAIL_CONTAINER_NAME") ]]; then
INSTALL_MAIL_SERVER="false";
fi
if [ "$MAKESWAP" == "true" ]; then
make_swap
fi
if command_exists docker ; then
check_docker_version
service docker start
else
install_docker
fi
docker_login
make_directories
set_partner_data
create_network
if [[ -z ${MYSQL_HOST} ]]; then
if [ "$INSTALL_MAIL_SERVER" == "true" ] || [ "$INSTALL_COMMUNITY_SERVER" == "true" ]; then
pull_mysql_server
install_mysql_server
elif [ "$INSTALL_MAIL_SERVER" == "pull" ] || [ "$INSTALL_COMMUNITY_SERVER" == "pull" ]; then
pull_mysql_server
fi
else
ping_host_port "$MYSQL_HOST" "$MYSQL_PORT"
fi
if [[ -z ${ELASTICSEARCH_HOST} ]]; then
if [ "$INSTALL_ELASTICSEARCH" == "true" ]; then
pull_elasticsearch
install_elasticsearch
elif [ "$INSTALL_ELASTICSEARCH" == "pull" ]; then
pull_elasticsearch
fi
else
ping_host_port "$ELASTICSEARCH_HOST" "$ELASTICSEARCH_PORT"
ELASTICSEARCH_SERVER="$ELASTICSEARCH_HOST";
fi
if [ "$INSTALL_DOCUMENT_SERVER" == "true" ]; then
pull_document_server
install_document_server
elif [ "$INSTALL_DOCUMENT_SERVER" == "pull" ]; then
pull_document_server
fi
if [ "$INSTALL_MAIL_SERVER" == "true" ]; then
pull_mail_server
install_mail_server
elif [ "$INSTALL_MAIL_SERVER" == "pull" ]; then
pull_mail_server
fi
if [ "$INSTALL_CONTROLPANEL" == "true" ]; then
pull_controlpanel
install_controlpanel
elif [ "$INSTALL_CONTROLPANEL" == "pull" ]; then
pull_controlpanel
fi
if [ "$INSTALL_COMMUNITY_SERVER" == "true" ]; then
pull_community_server
install_community_server
elif [ "$INSTALL_COMMUNITY_SERVER" == "pull" ]; then
pull_community_server
fi
[ -n "$JWT_MESSAGE" ] && [ -n "$DOCUMENT_SERVER_ID" ] && JWT_MESSAGE=$(echo "$JWT_MESSAGE" | sed 's/$(sudo docker ps -q)/'"${DOCUMENT_SERVER_ID::12}"'/') && echo -e "\n$JWT_MESSAGE"
echo ""
echo "Thank you for installing ONLYOFFICE."
echo "You can now configure your portal and add Mail Server to your installation (in case you skipped it earlier) using the Control Panel"
echo "In case you have any questions contact us via http://support.onlyoffice.com or visit our forum at http://forum.onlyoffice.com"
echo ""
exit 0;
}
start_installation
workspace-install.sh这个脚本主要的作用是检测安装环境并根据脚本选择执行相应的自动化安装部署过程,下面介绍如何离线化快速安装only office workspace
四、
workspace的具体离线部署步骤
镜像离线包下载地址:
通过网盘分享的文件:workspace
链接: https://pan.baidu.com/s/1_jnE5cmIizBB7djTJi0Xkg?pwd=hvbn 提取码: hvbn
--来自百度网盘超级会员v6的分享
相关脚本和所有镜像都在网盘内,onlyoffice-zong.tar 是所有镜像的压缩包方便传输,总共是五个镜像
搭建好docker环境后,导入上述五个镜像,即可开始执行workspace-install.sh,在执行此脚本前,还是需要先看看帮助(注意,这个帮助是install.sh这个脚本提供的,如果是bash workspace-install.sh -h,那么,install.sh这个脚本将会被删除):
root@centos14 ~]# bash install.sh -h
Usage: bash install.sh [PARAMETER] [[PARAMETER], ...]
Parameters:
-ci, --communityimage community image name or .tar.gz file path
-di, --documentimage document image name or .tar.gz file path
-mi, --mailimage mail image name or .tar.gz file path
-esi, --elasticsearchimage elasticsearch image name or .tar.gz file path
-cpi, --controlpanelimage control panel image name or .tar.gz file path
-mysqli, --mysqlimage mysql image name or .tar.gz file path
-cv, --communityversion community version
-dv, --documentversion document version
-dip, --documentserverip document server ip
-esv, --elasticsearchversion elasticsearch version
-esh, --elasticsearchhost elasticsearch server host
-msp, --elasticsearchport elasticsearch server port
-mv, --mailversion mail version
-mip, --mailserverip mail server ip
-mdbip, --mailserverdbip mail server db ip
-cpv, --controlpanelversion control panel version
-md, --maildomain mail domail name
-u, --update use to update existing components (true|false)
-hub, --hub dockerhub name
-un, --username dockerhub username
-p, --password dockerhub password
-ics, --installcommunityserver install or update community server (true|false|pull)
-ids, --installdocumentserver install or update document server (true|false|pull)
-ims, --installmailserver install or update mail server (true|false|pull)
-ies, --installelasticsearch install or update elasticsearch (true|false|pull)
-icp, --installcontrolpanel install or update control panel (true|false|pull)
-es, --useasexternalserver use as external server (true|false)
-pdf, --partnerdatafile partner data file
-it, --installation_type installation type (GROUPS|WORKSPACE|WORKSPACE_ENTERPRISE)
-ms, --makeswap make swap file (true|false)
-mysqlh, --mysqlhost mysql server host
-mysqlprt, --mysqlport mysql server port
-mysqlru, --mysqlrootuser mysql server root user
-mysqlrp, --mysqlrootpassword mysql server root password
-mysqld, --mysqldatabase community server database name
-mysqlu, --mysqluser community server database user
-mysqlp, --mysqlpassword community server database password
-mysqlmd, --mysqlmaildatabase mail server database name
-mysqlmu, --mysqlmailuser mail server database user
-mysqlmp, --mysqlmailpassword mail server database password
-skiphc, --skiphardwarecheck skip hardware check (true|false)
-skipvc, --skipversioncheck skip version check while update (true|false)
-skipdc, --skipdomaincheck skip domain check when installing mail server (true|false)
-cp, --communityport community port (default value 80)
-mk, --machinekey setting for core.machinekey
-je, --jwtenabled specifies the enabling the JWT validation (true|false)
-jh, --jwtheader defines the http header that will be used to send the JWT
-js, --jwtsecret defines the secret key to validate the JWT in the request
-?, -h, --help this help
Examples
Install all the solution components:
bash install.sh -md yourdomain.com
Install all the components without Mail Server:
bash install.sh -ims false
Install Document Server only. Skip the installation of Mail Server, Community Server and Control Panel:
bash install.sh -ics false -ids true -icp false -ims false -es true
Install Mail Server only. Skip the installation of Document Server, Community Server and Control Panel:
bash install.sh -ics false -ids false -icp false -ims true -md yourdomain.com -es true
Install Community Server with Control Panel and connect it with Document Server installed on a different machine which has the 192.168.3.202 IP address:
bash install.sh -ics true -icp true -ids false -ims false -dip 192.168.3.202
Update all installed components. Stop the containers that need to be updated, remove them and run the latest versions of the corresponding components. The portal data should be picked up automatically:
bash install.sh -u true
Update Document Server only to version 4.4.2.20 and skip the update for all other components:
bash install.sh -u true -dv 4.4.2.20 -ics false -icp false -ims false
Update Community Server only to version 9.1.0.393 and skip the update for all other components:
bash install.sh -u true -cv 9.1.0.393 -ids false -icp false -ims false
Update Mail Server only to version 1.6.27 and skip the update for all other components:
bash install.sh -u true -mv 1.6.27 -ics false -ids false -icp false
Update Control Panel only to version 2.1.0.93 and skip the update for all other components:
bash install.sh -u true -cpv 2.1.0.93 -ics false -ids false -ims false
install.sh这个脚本的变量可以按需修改成如下:
DISK_REQUIREMENTS=20960;
MEMORY_REQUIREMENTS=4000;
DOCUMENT_IMAGE_NAME="onlyoffice/documentserver";BASE_DIR="/opt3/$PRODUCT";
说明:onlyoffice/documentserver和onlyoffice/documentserver-ee一个是社区的镜像,一个是企业版的镜像,必须要改
DISK_REQUIREMENTS=20960;表示磁盘根目录的可用空间要求是2G,原来是需要5G
MEMORY_REQUIREMENTS=4000;表示需要内存是4G,原来是8G
BASE_DIR="/opt/$PRODUCT"; 如果要删除或者重新安装,先清除所有容器后,删除这个指定的目录,再次运行脚本即可,opt可以换成任意的目录,例如app,app1等等都可以
清除所有容器命令为:docker rm -f $(docker ps -aq)
结合上述帮助和现有镜像的版本,可以得出如下安装命令:
bash workspace-install.sh -dv 9.0.3.1 -cv 12.7.1.1942 -cpv 3.5.4.541 -esv 7.16.3 -cp 18080 -mysqli mysql_8.0.29.tar.gz -ims false
该命令注意是指定dv,cv,esv,cpv的版本,这些版本和现有的镜像版本是一一对应的关系(cv=community version,dv=document version,esv=elasticsearch version,cpv=control panel version),指定最终community的入口端口是18080,如果默认,是80端口,脚本执行的时候不提示mail server服务是否安装,直接忽略,还有一点必须强调,如果MySQL镜像没有docker load,或者其它镜像没有load,必须修改后缀为tar.gz 然后指定具体路径,
根据帮助命令,可以知道MySQL的端口,用户,密码等等都可以定制,如果需要的,比如,MySQL的密码设置为指定密码,-mysqlp 要设定的密码,加在上面的命令后面即可,cs的端口是18080,这个端口也可以随意更换,后面的示例是以18080端口演示的
安装日志如下(只要看到谢谢就表示安装成功完成了):
[root@centos14 ~]# bash workspace-install.sh -dv 9.0.3.1 -cv 12.7.1.1942 -cpv 3.5.4.541 -esv 7.16.3 -cp 18080 -mysqli mysql_8.0.29.tar.gz -ims false
Select 'Y' to install ONLYOFFICE using Docker (recommended). Select 'N' to install it using RPM/DEB packages.
Please note, that in case you select RPM/DEB installation, you will need to manually install Mail Server and connect it to your ONLYOFFICE installation.
See instructions in our Help Center: http://helpcenter.onlyoffice.com/server/docker/mail/connect-mail-server-to-community-server-via-portal-settings.aspx
Install with Docker [Y/N/C]? y
Redirecting to /bin/systemctl start docker.service
Loaded image: mysql:8.0.29
d35786c1e44ee0daa5cb23f8353fc24a505d6cc437f9bd7105918b9aca45e39f
4badf9013bd49ab4126ddd30bee00813e449774b0593224fa9a54e616c4a6e1e
cfe44b02916b1dc9b0a2e32dbb9bd0ddcbbf58408f2feead3fd0fea4c07966f4
85bafe7069ad931fb7cf29a235d1c0523ad010b28792293788be2912abc03aba
ecc564d4038b777ba8fbf35f617c3a5d4b6a8f797b6d16be620b2b2a838f9e7a
JWT is enabled by default. A random secret is generated automatically. Run the command "docker exec cfe44b02916b sudo documentserver-jwt-status.sh" to get information about JWT.
Thank you for installing ONLYOFFICE.
You can now configure your portal and add Mail Server to your installation (in case you skipped it earlier) using the Control Panel
In case you have any questions contact us via http://support.onlyoffice.com or visit our forum at http://forum.onlyoffice.com
各个服务的大体日志
所有服务都是up状态
[root@centos14 ~]# docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
ecc564d4038b onlyoffice/communityserver:12.7.1.1942 "/app/run-community-…" 4 minutes ago Up 4 minutes 0.0.0.0:443->443/tcp, :::443->443/tcp, 3306/tcp, 5280/tcp, 9865-9866/tcp, 9871/tcp, 9882/tcp, 0.0.0.0:5222->5222/tcp, :::5222->5222/tcp, 9888/tcp, 0.0.0.0:18080->80/tcp, [::]:18080->80/tcp onlyoffice-community-server
85bafe7069ad onlyoffice/controlpanel:3.5.4.541 "/var/www/onlyoffice…" 4 minutes ago Up 4 minutes 80/tcp, 443/tcp onlyoffice-control-panel
cfe44b02916b onlyoffice/documentserver:9.0.3.1 "/app/ds/run-documen…" 4 minutes ago Up 4 minutes 80/tcp, 443/tcp onlyoffice-document-server
4badf9013bd4 onlyoffice/elasticsearch:7.16.3 "/bin/tini -- /usr/l…" 4 minutes ago Up 4 minutes 9200/tcp, 9300/tcp onlyoffice-elasticsearch
d35786c1e44e mysql:8.0.29 "docker-entrypoint.s…" 4 minutes ago Up 4 minutes 3306/tcp, 33060/tcp
ds的:
[ OK ] Started ONLYOFFICE Thumb Service.
[ OK ] Started ONLYOFFICE SsoAuth Service.
[ OK ] Started System Logging Service.
[ OK ] Started LSB: Mono XSP4.
[ OK ] Started God Service.
[ OK ] Started A high performance web server and a reverse proxy server.
[ OK ] Started Advanced key-value store.
[ OK ] Started MySQL Community Server.
Starting FastCGI Mono server...
Starting FastCGI Mono server...
Starting Start ONLYOFFICE Backup Service...
Starting ONLYOFFICE Feed Service...
Starting ONLYOFFICE FilesTrashCleaner Service...
Starting Start ONLYOFFICE Index Service...
Starting ONLYOFFICE Jabber Service...
Starting ONLYOFFICE MailAggregator Service...
Starting ONLYOFFICE MailCleaner Service...
Starting ONLYOFFICE MailImap Service...
Starting ONLYOFFICE MailWatchdog Service...
Starting ONLYOFFICE Notify Service...
Starting ONLYOFFICE Radicale Service...
Starting ONLYOFFICE SocketIO Service...
Starting Start ONLYOFFICE StorageEncryption Service...
Starting Start ONLYOFFICE StorageMigrate Service...
Starting ONLYOFFICE Telegram Service...
Starting ONLYOFFICE ThumbnailBuilder Service...
Starting ONLYOFFICE UrlShortener Service...
Starting ONLYOFFICE WebDav Service...
[ OK ] Started FastCGI Mono server.
[ OK ] Started ONLYOFFICE Radicale Service.
[ OK ] Started ONLYOFFICE SocketIO Service.
[ OK ] Started ONLYOFFICE UrlShortener Service.
[ OK ] Started FastCGI Mono server.
[ OK ] Started ONLYOFFICE WebDav Service.
[ OK ] Started ONLYOFFICE Feed Service.
[ OK ] Started ONLYOFFICE FilesTrashCleaner Service.
[ OK ] Started Start ONLYOFFICE Index Service.
[ OK ] Started Start ONLYOFFICE Backup Service.
[ OK ] Started ONLYOFFICE Jabber Service.
[ OK ] Started ONLYOFFICE Notify Service.
[ OK ] Started Start ONLYOFFICE StorageEncryption Service.
[ OK ] Started Start ONLYOFFICE StorageMigrate Service.
[ OK ] Started ONLYOFFICE Telegram Service.
[ OK ] Started ONLYOFFICE ThumbnailBuilder Service.
[ OK ] Started ONLYOFFICE MailCleaner Service.
[ OK ] Started ONLYOFFICE MailImap Service.
[ OK ] Started ONLYOFFICE MailWatchdog Service.
[ OK ] Started ONLYOFFICE MailAggregator Service.
[ OK ] Reached target Multi-User System.
[ OK ] Reached target Graphical Interface.
cp的日志:
[root@centos14 ~]# docker logs 85bafe7069ad
2025-08-06 16:04:27,015 INFO Included extra file "/etc/supervisor/conf.d/supervisord.conf" during parsing
2025-08-06 16:04:27,015 INFO Set uid to user 0 succeeded
2025-08-06 16:04:27,017 INFO RPC interface 'supervisor' initialized
2025-08-06 16:04:27,017 CRIT Server 'unix_http_server' running without any HTTP authentication checking
2025-08-06 16:04:27,018 INFO supervisord started with pid 1
2025-08-06 16:04:28,020 INFO spawned: 'www' with pid 16
2025-08-06 16:04:29,148 INFO success: www entered RUNNING state, process has stayed up for > than 1 seconds (startsecs)
ds的日志:
[root@centos14 ~]# docker logs 85bafe7069ad
2025-08-06 16:04:27,015 INFO Included extra file "/etc/supervisor/conf.d/supervisord.conf" during parsing
2025-08-06 16:04:27,015 INFO Set uid to user 0 succeeded
2025-08-06 16:04:27,017 INFO RPC interface 'supervisor' initialized
2025-08-06 16:04:27,017 CRIT Server 'unix_http_server' running without any HTTP authentication checking
2025-08-06 16:04:27,018 INFO supervisord started with pid 1
2025-08-06 16:04:28,020 INFO spawned: 'www' with pid 16
2025-08-06 16:04:29,148 INFO success: www entered RUNNING state, process has stayed up for > than 1 seconds (startsecs)
MySQL的日志:
[root@centos14 ~]# docker logs d35786c1e44e
2025-08-06 16:04:24+00:00 [Note] [Entrypoint]: Entrypoint script for MySQL Server 8.0.29-1.el8 started.
2025-08-06 16:04:24+00:00 [Note] [Entrypoint]: Switching to dedicated user 'mysql'
2025-08-06 16:04:25+00:00 [Note] [Entrypoint]: Entrypoint script for MySQL Server 8.0.29-1.el8 started.
'/var/lib/mysql/mysql.sock' -> '/var/run/mysqld/mysqld.sock'
2025-08-06 16:04:46+00:00 [Note] [Entrypoint]: Entrypoint script for MySQL Server 8.0.29-1.el8 started.
2025-08-06 16:04:46+00:00 [Note] [Entrypoint]: Switching to dedicated user 'mysql'
2025-08-06 16:04:46+00:00 [Note] [Entrypoint]: Entrypoint script for MySQL Server 8.0.29-1.el8 started.
'/var/lib/mysql/mysql.sock' -> '/var/run/mysqld/mysqld.sock'
2025-08-06 16:04:54+00:00 [Note] [Entrypoint]: Entrypoint script for MySQL Server 8.0.29-1.el8 started.
2025-08-06 16:04:55+00:00 [Note] [Entrypoint]: Switching to dedicated user 'mysql'
2025-08-06 16:04:55+00:00 [Note] [Entrypoint]: Entrypoint script for MySQL Server 8.0.29-1.el8 started.
'/var/lib/mysql/mysql.sock' -> '/var/run/mysqld/mysqld.sock'
elasticsearch的日志:
{"type": "server", "timestamp": "2025-08-06T16:04:37,112Z", "level": "INFO", "component": "o.e.n.Node", "cluster.name": "docker-cluster", "node.name": "4badf9013bd4", "message": "initialized" }
{"type": "server", "timestamp": "2025-08-06T16:04:37,113Z", "level": "INFO", "component": "o.e.n.Node", "cluster.name": "docker-cluster", "node.name": "4badf9013bd4", "message": "starting ..." }
{"type": "server", "timestamp": "2025-08-06T16:04:37,136Z", "level": "INFO", "component": "o.e.x.s.c.f.PersistentCache", "cluster.name": "docker-cluster", "node.name": "4badf9013bd4", "message": "persistent cache index loaded" }
{"type": "server", "timestamp": "2025-08-06T16:04:37,137Z", "level": "INFO", "component": "o.e.x.d.l.DeprecationIndexingComponent", "cluster.name": "docker-cluster", "node.name": "4badf9013bd4", "message": "deprecation component started" }
{"type": "server", "timestamp": "2025-08-06T16:04:37,210Z", "level": "INFO", "component": "o.e.t.TransportService", "cluster.name": "docker-cluster", "node.name": "4badf9013bd4", "message": "publish_address {172.18.0.3:9300}, bound_addresses {[::]:9300}" }
{"type": "server", "timestamp": "2025-08-06T16:04:37,559Z", "level": "WARN", "component": "o.e.b.BootstrapChecks", "cluster.name": "docker-cluster", "node.name": "4badf9013bd4", "message": "max virtual memory areas vm.max_map_count [65530] is too low, increase to at least [262144]" }
{"type": "server", "timestamp": "2025-08-06T16:04:37,561Z", "level": "INFO", "component": "o.e.c.c.Coordinator", "cluster.name": "docker-cluster", "node.name": "4badf9013bd4", "message": "cluster UUID [klSQapPZSYKDT2plZiD0PQ]" }
{"type": "server", "timestamp": "2025-08-06T16:04:37,858Z", "level": "INFO", "component": "o.e.c.s.MasterService", "cluster.name": "docker-cluster", "node.name": "4badf9013bd4", "message": "elected-as-master ([1] nodes joined)[{4badf9013bd4}{El-Y0vaIQlyQDa8pkj1Egw}{HgomzK-ARq6VtRd8ViQlYg}{172.18.0.3}{172.18.0.3:9300}{cdfhilmrstw} elect leader, _BECOME_MASTER_TASK_, _FINISH_ELECTION_], term: 10, version: 288, delta: master node changed {previous [], current [{4badf9013bd4}{El-Y0vaIQlyQDa8pkj1Egw}{HgomzK-ARq6VtRd8ViQlYg}{172.18.0.3}{172.18.0.3:9300}{cdfhilmrstw}]}" }
{"type": "server", "timestamp": "2025-08-06T16:04:37,929Z", "level": "INFO", "component": "o.e.c.s.ClusterApplierService", "cluster.name": "docker-cluster", "node.name": "4badf9013bd4", "message": "master node changed {previous [], current [{4badf9013bd4}{El-Y0vaIQlyQDa8pkj1Egw}{HgomzK-ARq6VtRd8ViQlYg}{172.18.0.3}{172.18.0.3:9300}{cdfhilmrstw}]}, term: 10, version: 288, reason: Publication{term=10, version=288}" }
{"type": "server", "timestamp": "2025-08-06T16:04:37,975Z", "level": "INFO", "component": "o.e.h.AbstractHttpServerTransport", "cluster.name": "docker-cluster", "node.name": "4badf9013bd4", "message": "publish_address {172.18.0.3:9200}, bound_addresses {[::]:9200}", "cluster.uuid": "klSQapPZSYKDT2plZiD0PQ", "node.id": "El-Y0vaIQlyQDa8pkj1Egw" }
{"type": "server", "timestamp": "2025-08-06T16:04:37,975Z", "level": "INFO", "component": "o.e.n.Node", "cluster.name": "docker-cluster", "node.name": "4badf9013bd4", "message": "started", "cluster.uuid": "klSQapPZSYKDT2plZiD0PQ", "node.id": "El-Y0vaIQlyQDa8pkj1Egw" }
{"type": "server", "timestamp": "2025-08-06T16:04:38,416Z", "level": "INFO", "component": "o.e.l.LicenseService", "cluster.name": "docker-cluster", "node.name": "4badf9013bd4", "message": "license [9c141f58-1d95-41e2-9d29-2e37eba460a1] mode [basic] - valid", "cluster.uuid": "klSQapPZSYKDT2plZiD0PQ", "node.id": "El-Y0vaIQlyQDa8pkj1Egw" }
{"type": "server", "timestamp": "2025-08-06T16:04:38,418Z", "level": "INFO", "component": "o.e.x.s.s.SecurityStatusChangeListener", "cluster.name": "docker-cluster", "node.name": "4badf9013bd4", "message": "Active license is now [BASIC]; Security is disabled", "cluster.uuid": "klSQapPZSYKDT2plZiD0PQ", "node.id": "El-Y0vaIQlyQDa8pkj1Egw" }
{"type": "server", "timestamp": "2025-08-06T16:04:38,418Z", "level": "WARN", "component": "o.e.x.s.s.SecurityStatusChangeListener", "cluster.name": "docker-cluster", "node.name": "4badf9013bd4", "message": "Elasticsearch built-in security features are not enabled. Without authentication, your cluster could be accessible to anyone. See https://www.elastic.co/guide/en/elasticsearch/reference/7.16/security-minimal-setup.html to enable security.", "cluster.uuid": "klSQapPZSYKDT2plZiD0PQ", "node.id": "El-Y0vaIQlyQDa8pkj1Egw" }
{"type": "deprecation.elasticsearch", "timestamp": "2025-08-06T16:04:38,419Z", "level": "CRITICAL", "component": "o.e.d.x.s.s.SecurityStatusChangeListener", "cluster.name": "docker-cluster", "node.name": "4badf9013bd4", "message": "The default behavior of disabling security on basic licenses is deprecated. In a later version of Elasticsearch, the value of [xpack.security.enabled] will default to \"true\" , regardless of the license level. See https://www.elastic.co/guide/en/elasticsearch/reference/7.16/security-minimal-setup.html to enable security, or explicitly disable security by setting [xpack.security.enabled] to false in elasticsearch.yml", "key": "security_implicitly_disabled", "category": "security", "cluster.uuid": "klSQapPZSYKDT2plZiD0PQ", "node.id": "El-Y0vaIQlyQDa8pkj1Egw" }
{"type": "server", "timestamp": "2025-08-06T16:04:38,425Z", "level": "INFO", "component": "o.e.g.GatewayService", "cluster.name": "docker-cluster", "node.name": "4badf9013bd4", "message": "recovered [27] indices into cluster_state", "cluster.uuid": "klSQapPZSYKDT2plZiD0PQ", "node.id": "El-Y0vaIQlyQDa8pkj1Egw" }
{"type": "server", "timestamp": "2025-08-06T16:04:39,943Z", "level": "INFO", "component": "o.e.c.r.a.AllocationService", "cluster.name": "docker-cluster", "node.name": "4badf9013bd4", "message": "Cluster health status changed from [RED] to [YELLOW] (reason: [shards started [[.ds-.logs-deprecation.elasticsearch-default-2025.08.05-000001][0]]]).", "cluster.uuid": "klSQapPZSYKDT2plZiD0PQ", "node.id": "El-Y0vaIQlyQDa8pkj1Egw" }
这些镜像的实际运行命令如下(基本比较准确,但不可直接使用):
[root@centos20 initdb]# runlike -p b5ea0b17c311
docker run --name=onlyoffice-mysql-server \
--hostname=b5ea0b17c311 \
--volume /app/onlyoffice/mysql/initdb:/docker-entrypoint-initdb.d \
--volume /app/onlyoffice/mysql/conf.d:/etc/mysql/conf.d \
--volume /app/onlyoffice/mysql/data:/var/lib/mysql \
--volume /app/onlyoffice/mysql/logs:/var/log/mysql \
--env=MYSQL_ROOT_PASSWORD=my-secret-pw \
--env=MYSQL_DATABASE=onlyoffice \
--network=onlyoffice \
--expose=3306 \
--expose=33060 \
--restart=always \
--log-opt max-size=100m \
--runtime=runc \
--detach=true \
-t \
mysql:8.0.29 \
mysqld
[root@centos20 initdb]# runlike -p 3dc60e58f3c4
docker run --name=onlyoffice-elasticsearch \
--hostname=3dc60e58f3c4 \
--volume /app/onlyoffice/elasticsearch/data:/usr/share/elasticsearch/data \
--env=indices.memory.index_buffer_size=30% \
--env=discovery.type=single-node \
--env=bootstrap.memory_lock=true \
--env=ingest.geoip.downloader.enabled=false \
--env='ES_JAVA_OPTS=-Xms1g -Xmx1g -Dlog4j2.formatMsgNoLookups=true' \
--env=indices.fielddata.cache.size=30% \
--network=onlyoffice \
--workdir=/usr/share/elasticsearch \
--expose=9200 \
--expose=9300 \
--restart=always \
--log-opt max-size=100m \
--runtime=runc \
--detach=true \
-t \
onlyoffice/elasticsearch:7.16.3 \
eswrapper
[root@centos20 initdb]# runlike -p e1d29769643d
docker run --name=onlyoffice-ds \
--hostname=e1d29769643d \
--volume /var/lib/postgresql \
--volume /var/lib/rabbitmq \
--volume /var/lib/redis \
--volume /var/log/onlyoffice \
--volume /app/ds/data:/var/www/onlyoffice/Data \
--volume /app/ds/fonts:/usr/share/fonts/truetype/custom \
--volume /var/lib/onlyoffice \
--network=onlyoffice \
--expose=443 \
-p 9001:80 \
--log-opt max-size=100m \
--runtime=runc \
--detach=true \
onlyoffice/documentserver:9.0.3.1
[root@centos20 initdb]# runlike -p 6ee11342a288
docker run --name=onlyoffice-cs \
--hostname=6ee11342a288 \
--volume /app/onlyoffice/CommunityServer/logs:/var/log/onlyoffice \
--volume /app/onlyoffice/CommunityServer/letsencrypt:/etc/letsencrypt \
--volume /sys/fs/cgroup:/sys/fs/cgroup \
--volume /var/lib/mysql \
--volume /app/onlyoffice/CommunityServer/data:/var/www/onlyoffice/Data \
--env=MYSQL_SERVER_ROOT_PASSWORD=my-secret-pw \
--env=MYSQL_SERVER_DB_NAME=onlyoffice \
--env=MYSQL_SERVER_HOST=onlyoffice-mysql-server \
--env=MYSQL_SERVER_USER=onlyoffice_user \
--env=MYSQL_SERVER_PASS=onlyoffice_pass \
--network=onlyoffice \
--privileged \
--expose=3306 \
-p 443:443 \
-p 5222:5222 \
--expose=5280 \
-p 9100:80 \
--expose=9865 \
--expose=9866 \
--expose=9871 \
--expose=9882 \
--expose=9888 \
--restart=always \
--log-opt max-size=100m \
--runtime=runc \
--detach=true \
-t \
onlyoffice/communityserver:12.7.1.1942 \
/app/run-community-server.sh
docker run --name=onlyoffice-control-panel \
--hostname=631ff4d76db1 \
--volume /var/run/docker.sock:/var/run/docker.sock \
--volume /app/onlyoffice/ControlPanel/data:/var/www/onlyoffice/Data \
--volume /app/onlyoffice/CommunityServer/data:/app/onlyoffice/CommunityServer/data \
--volume /app/onlyoffice/ControlPanel/logs:/var/log/onlyoffice \
--env=ONLYOFFICE_CORE_MACHINEKEY=vwqZSf6gOzkj \
--network=onlyoffice \
--workdir=/var/www/onlyoffice/controlpanel \
--expose=443 \
--expose=80 \
--restart=always \
--runtime=runc \
--detach=true \
-t \
onlyoffice/controlpanel:3.5.4.541
现在就可以打开浏览器进入workspace了:
密码8位以上,时区选上海,语言选中文或者英文都可以,邮箱可随意填写,但必须是邮箱格式,邮箱就是管理员账号,完成后,点击continue
第一次输入的密码和邮箱就是管理员的账号和密码了,记得妥善保存噢
离线化安装workspace基本可以做到2 3分钟内就完成,前提是docker环境是正确配置好的并导入了五个网盘内的镜像
五、
workspace业务简单介绍
创建用户
当我们使用管理员进入系统后,如果希望其它人能够也访问此系统,那么,创建添加用户是必须的,这个非常简单,找People,点击进入后,创建即可
记得把美照也上传上去,红星的必填填写完就可以了,然后保存
创建项目
项目是最核心的功能,要记得添加成员噢
上传文档到上面创建的项目内:
点击创建好的项目,选择documents标签,可以看到多一个上传的入口:
当然了,随便什么word,excel也是非常简单的就可以打开了,只是注意有时候会有乱码,乱码的问题以后在说