运行和部署教程
本文解释如何通过以下方式运行Moqui:
- 可执行war文件
- 在一个应用服务器中部署一个war文件
{toc}
1. 快速启动
Moqui框架默认配置唯一需要的软件是 Java SE JDK v8。如果你没有在用OpenJDK(apt: openjdk-8-jdk , yum: java-1.8.0-openjdk-devel),那么一般最好从 Oracle的Java SE 下载。
Moqui框架也包含一个ElasticSearch客户端,适用于ElasticSearch 7.0 或以上版本。 推荐使用的版本是不带JDK构建出来的 OSS (Apache 2.0授权)。 如果ElasticSearch在localhost:9200端口可用,默认配置的Moqui将找到它,否则请查阅 这里配置、环境变量等的更多选项。
使用Moqui二进制发布包快速启动
- 在 最新发布 中下载二进制包
- 加载种子和demo数据(将自动创建H2数据库和表)
java -jar moqui.war load
- 运行框架(使用嵌入式的Servlet容器,事务管理器,数据库):
java -jar moqui.war
- 在(同一台机的)浏览器中访问:
http://localhost:8080
- 如果是使用准备好的示例组件、已加载的演示数据,可用用户名“john.doe”和密码“moqui”登录
从源代码带ElasticSearch快速启动
通过以下步骤从源代码开始完成本地安装,带默认的嵌入式数据库(H2)并把ElasticSearch安装在runtime/elasticsearch目录。
- 克隆 moqui-framework 仓库
git clone https://github.com/moqui/moqui-framework.git moqui cd moqui
- 获取期望的组件,以PopCommerce和HiveMind为例:
./gradlew getComponent -Pcomponent=PopCommerce ./gradlew getComponent -Pcomponent=HiveMind
- 如果什么组件都不想要,也可以只获取默认的runtime目录
./gradlew getRuntime
- 如果什么组件都不想要,也可以只获取默认的runtime目录
- 下载 ElasticSearch(Linux OSS 无JDK版本)
./gradlew downloadElasticSearchLinux
- 构建后加载种子和演示数据(load任务依赖build任务)
./gradlew load
- 启动 Moqui 同时运行 ElasticSearch (如果不运行 ElasticSearch, 添加 'no-run-es'')
java -jar moqui.war
- 在浏览器中访问 http://localhost:8080
用 Docker Compose 从源代码快速启动
通过下述步骤来从源代码在本地安装,使用的数据库和ElasticSearch为和Moqui分离的Docker容器。这在Linux上工作得最好,但也能被用于某些MacOS和Windows。
- 安装 Docker (docker-ce) 和 Docker Compose (docker-compose),确信你的用户在'docker' 组。参考:
- 克隆 moqui-framework 仓库
git clone https://github.com/moqui/moqui-framework.git moqui
cd moqui
- 获取期望的组件,以PopCommerce和HiveMind为例:
./gradlew getComponent -Pcomponent=PopCommerce
./gradlew getComponent -Pcomponent=HiveMind
* 如果什么组件都不想要,也可以只获取默认的runtime目录
```
./gradlew getRuntime
```
构建Moqui并创建moqui-plus-runtime.war文件
./gradlew addRuntime
使用默认名字 moqui 构建一个本地Docker镜像(要使用不同的组/名、push到Docker仓库等,请阅读后面的Docker章节)
cd docker/simple ./docker-build.sh
如果出现下面的错,可以先将 HEALTHCHECK 行注释掉
Step 16/17 : HEALTHCHECK --interval=30s --timeout=600ms --start-period=120s CMD curl -f -H "X-Forwarded-Proto: https" -H "X-Forwarded-Ssl: on" http://localhost/status || exit 1 Unknown flag: start-period
回到 docker 目录
cd ..
创建一个 Docker Compose YML 文件,可以拿docker目录中的一个作参考
使用 compose-up.sh 脚本启动已配置的容器(文件名可替换为你中意的)
./compose-up.sh moqui-ng-my-compose.yml
- 当Moqui第一次启动时,它将判断数据库是否为空(Enumeration实体表中没有数据),并自动加载已配置的数据集。使用默认的包含所有 seed 、 seed-initial 和 install 数据文件的MoquiProductionConf.xml文件
如果你使用的这些默认文件中,nginx-proxy配置VIRTUAL_HOST被设置为 moqui.local,那么在 /etc/hosts 文件中类似如下加一行:
127.0.0.1 moqui.local
- 在浏览器中访问 Moqui
- 在你的浏览器中访问 https://moqui.local 或你配置的主机
- 如果你使用的是 moqui.local,并且包含了自签名的证书,你将会在浏览器中收到安全警告
- 当你第一次访问Moqui时,数据库中还没有用户,登录界面将显示一个创建一个管理员用户的表单。
- 停止已配置的容器(确保使用的YML文件和用来启动YML文件一样)
- 清理已映射的目录(如果你想移除数据库等内容来重新开始;注意这需要root权限,因为映射到主机文件系统的数据库和其他文件夹是root所有的)
Really Quick Start
- 下载 MoquiDemo-
.war 文件 - 把这个war文件放入Java Servlet容器(Jetty, Apache Tomcat, AWS ElasticBeanstalk等等)
2. 运行时(runtime)目录和配置文件
Moqui框架要部署的有2个主要部分:
- 可执行WAR文件(如下,来自 moqui-framework 仓库)
- 有配置文件的运行时目录(来自 moqui-runtime 或者您自己的仓库)
然而使用可执行WAR文件,你必须有一个运行时目录并且你可以用一个XML配置文件覆盖默认设置。
Moqui框架的所有配置都在Moqui配置XML文件中。运行时被使用的实际的配置XML文件按以下顺序合并多个XML文件生成:
- 构建的WAR文件中包含的,框架自带的 MoquiDefaultConf.xml
- 每个组件的 MoquiConf.xml
- 特定的运行时Moqui配置XML文件,例如 MoquiDevConf.xml 或 MoquiProductionConf.xml
运行时目录是放置要加载的组件、web应用的根文件(根界面等等)和配置文件的主要位置。 它也是框架将放置日志文件、(使用H2数据库时的)数据库文件、JCR仓库文件等等。 你可能会想创建你自己的运行时目录并将其保存在你自己的代码仓库里(fork moqui-runtime 仓库),但你刚开始可以使用默认的。在moqui-runtime中通常你想覆盖或扩展的内容都可以在你自己的附加组件内完成。
指定这两个属性:
| {{moqui.runtime}} | 运行时目录,(默认是"./runtime") | | {{moqui.conf}} | XML配置文件(URL或相对于mqui.runtime的相对路径)|
有两种方式来指定这两个属性:
- 类路径上的 {{MoquiInit.properties}} 文件
- 通过命令行(用 java -D 参数)指定的系统属性
示例如下。
3. 可执行的WAR文件
使用可执行文件可以做的事情(示例命令仅作演示用,请按需修改):
命令例子 | |
---|---|
加载数据: | {{$ java -jar moqui.war load}} |
运行内嵌的web服务器: | {{$ java -jar moqui.war}} |
作为WAR部署,以Tomcat为例: | {{$ cp moqui.war ../tomcat/webapps/ROOT.war}} |
还可以显示设置和帮助信息:
java -jar moqui.war -help
如何只加载指定的文件,而不是所有组件中的所有数据文件,可以运行这个命令来查看帮助文本。
4. 示例和通用方法
简单方式 - 默认设置
运行的最简单的方式是有一个内有moqui.war文件和runtime目录的的moqui目录。你解压moqui分发的二进制压缩文件后就有了。
使用默认设置:
- moqui.runtime = runtime
- moqui.conf = conf/MoquiDevConf.xml (相当于runtime)
运行这些命令:
命令例子 | |
---|---|
加载数据 | {{$ java -jar moqui.war load}} |
运行服务器 | {{$ java -jar moqui.war}} |
Common Alternate - 在命令行指定一个配置文件
命令例子 | |
---|---|
加载数据 | {{$ java -jar moqui.war load conf=conf/MoquiProductionConf.xml}} |
运行服务器 | {{$ java -jar moqui.war conf=conf/MoquiProductionConf.xml}} |
创建一个带自定义配置的WAR文件
- 把需要的组件和其他资源加到 runtime 目录
- 修改 ${moqui.home}/MoquiInit.properties 中的设置
- 按需修改 Moqui 配置文件 (runtime/conf/Moqui*Conf.xml)
- 基于 moqui.war 文件和你的runtime目录的内容创建一个衍生的WAR文件
- 将创建的WAR文件(moqui-plus-runtime.war)复制的部署目的地
- 运行服务器(或重起以部署WAR)
5. 组件管理
管理组件源代码仓库的最好方法是每个组件都(在GitHub或其他地方)有一个仓库,只包含组件目录。
按这种模式,Moqui中的 Gradle 构建脚本有任务来从一个git仓库或从当前、已发布归档中下载组件及其依赖。
已知的开源组件已经配置在 {{addons.xml}} 文件中。 为了增加私有和其他组件或者覆盖 addons.xml 中组件的设置,创建一个名为 {{myaddons.xml}} 的文件并放在 moqui 目录中。
下面是 Gradle 组件管理任务概要(以HiveMind组件为例)。 所有的获取任务获取指定的组件及其(在component.xml文件中指定的)所有依赖组件。
获取 runtime 目录
./gradlew getRuntime -PlocationType=(git,current,release)\}\}
- 如果 runtime 目录不存在,则会自动调用
- 如果 .git 目录存在,则 location type 默认为 git,否则为 currnet
获取组件
./gradlew getComponent -Pcomponent=HiveMind -PlocationType=(git,current,release)}
- 如果 .git 目录存在,则 location type 默认为 git,否则为 currnet
从Git仓库获取
./gradlew getGit -Pcomponent=HiveMind
获取当前归档
./gradlew getCurrent -Pcomponent=HiveMind
获取已发布的归档
./gradlew getRelease -Pcomponent=HiveMind
获取所有组件的依赖
./gradlew getDepends -PlocationType=(git,current,release)
- 如果 .git 目录存在,则 location type 默认为 git,否则为 currnet
还有帮助从git管理组件的Gradle任务。这些命令在moqui(根)仓库、runtime仓库和所有组件有.git目录存在时执行git操作。
命令例子 | |
---|---|
Git pull all | {{$ ./gradlew gitPullAll}} |
Git status on all | {{$ ./gradlew gitStatusAll}} |
Git pull upstream on all | {{$ ./gradlew gitUpstreamAll}} |
Clean all, pull all, load data | {{$ ./gradlew cleanPullLoad}} |
Clean all, pull all, load data, all tests | {{$ ./gradlew cleanPullTest}} |
Clean all, pull all, load data, only component tests | {{$ ./gradlew cleanPullCompTest}} |
6. 从源代码构建和运行
Moqui框架使用Gradlel来从源代码构建。有各种自定义任务来自动化处理高频内容,但是大部分工作是Gradle的内置任务完成的。
对一些通用任务也有一个Ant文件,但是不是用来从源代码构建的。
目标 | gradle 命令 | ant 命令 |
---|---|---|
获取组件和依赖 (以HiveMind为例) | {{$ ./gradlew getComponent -Pcomponent=HiveMind}} | |
构建 JAR, WAR | {{$ ./gradlew build}} | |
加载所有数据 | {{$ ./gradlew load}} | {{$ ant load}} |
运行嵌入式服务器 | {{$ ./gradlew run}} | {{$ ant run}} |
创建带嵌入runtime的WAR | {{$ ./gradlew addRuntime}} | {{$ ant add-runtime}} |
清理JAR, WAR | {{$ ./gradlew clean}} | |
清理所有已构建和运行时文件 (日志, 数据库文件等) | {{$ ./gradlew cleanAll}} |
上述示例使用 Moqui 包含有的 Gradle Wrapper (gradlew)。你也可以安装Gradle(2.0或以上)。 加载(load)和运行(run)任务依赖构建(build)任务,所以最简单能获取一个运行常用数据库的新开发环境的系统的方法是:
环境 | 命令 |
---|---|
Linux/Mac Gradle Wrapper | {{$ ./gradlew load run}} |
Windows Gradle Wrapper | {{> gradlew.bat load run}} |
Installed Gradle | {{$ gradle load run}} |
这将构建war文件,运行数据加载器,然后运行服务器。要停止它只要按ctrl-c就可以了。
7. ElasticSearch配置和安装
外部 ElasticSearch
在生产环境通常是有一个外部的ElasticSearch集群,和Moqui服务器/集群分开运行。 这也能用于本地开发,启停、清数据等等都和Moqui或Moqui Gradle任务分开。 ElasticSearch版本7.0.0或以后(OSS与否、有没有JDK、使用Elastic/AWS主机等等)都可以这么做。 如果你在安装ElasticSearch, 推荐的是 不带JDK的OSS版本。
Moqui配置XML文件中的ElasticSearch集群配置在 MoquiDefaultConf.xml文件中的一个'default'集群,其使用环境变量(或Java系统属性)以更易于配置。可用的ElasticSearch和其他环境变量请查阅后续章节。 如果你使用的ElasticSearch不需要HTTP Basic鉴定,那么唯一需要配置的环境变量(属性)是 elasticsearch_url,默认值为 http://localhost:9200
安装在Runtime中的ElasticSearch
ElasticSearch 可被安装在 runtime/elasticsearch 目录中,并在Moqui(通过MoquiStart)启动时运行,同时通过多个Gradle任务启动、停止以及数据清理。 在本地开发环境中,通常是运行一个ElasticSearch本地实例,并在清理H2数据库数据时清理ElasticSearch数据。 这也能用在你不需要或者不想用单独的ElasticSearch集群的时候。
注意当前对“在MoquiStart和Gradle任务中把ElasticSearch安装在runtime/elasticsearch中”的支持仅限于Unix家族(如Linux,MacOS)使用OSS no-JDK版本。 现在还不能在Windows机器上工作,所以如果你在Windows上开发,需要独立安装管理ElasticSearch,确保它在http://localhost:9200(或配置elasticsearch_url指向的其他地方)可用。
确保设置了 JAVA_HOME 环境变量,这样 ElasticSearch 才知道在哪可找到Java JDK。
要把ElasticSearch安装到runtime/elasticsearch中,最简单的方法是使用Gradle任务。这将下载ElasticSearch的OSS无JDK的Linux发布包,并在runtime/elasticsearch目录内解压缩。
./gradlew downloadElasticSearchLinux
在Gradle中,有startElasticSearch和stopElasticSearch任务。注意Gradle支持精简的任务名称,只要能匹配到单个任务。所以你能使用短一点的任务名,例如 downloadel,startel和stopel。
./gradlew startel
./gradlew stopel
这些将在尝试启动或停止时输出信息。如果没有找到安装的ElasticSearch(runtime/elasticsearch/bin目录不存在)或发现ElasticSearch已经在运行或未运行(如果runtime/elasticsearch/pid文件存在则表示在运行)时就啥也不做。 因此如果你不确定ElasticSearch是否在运行,你可以运行 startel 来确定它在运行,或 stopel 来确定它没运行。
cleanDb、load、loadSave、reloadSave和test任务都会顾及runtime/elasticsearch。 如果ES在运行(pid文件存在),cleanDB将会停止ES,删除数据目录然后启动ES。 注意如果bin目录存在(检测到ES有安装)并且pid文件不存在,test任务自动启动ES,但是现在它在运行完所有测试之后不会停止ES。
MoquiStart类将会在发现有'bin'目录时尝试启动安装在runtime/elasticsearch中的ElasticSearch。 要禁止这个行为,使用'no-run-es'参数。要使用这个,只需要按以下方式运行Moqui:
java -jar moqui.war
有load参数时也可以,例如:
java -jar moqui.war load
这将在Moqui起停时同时启停ElasticSearch,用Runtime.exec()在一个fork出来的进程中运行ElasticSearch。 注意在上例中,当用 java -jar 运行可指向WAR时,使用了 MoquiStart 类。当在接开了的WAR文件根目录运行时,会像这样:
java -cp . MoquiStart port=5000 conf=conf/MoquiProductionConf.xml
当你把嵌入式WAR文件放在外部Servlet容器(如Tomcat、Jetty)时,MoquiStart类是不会被使用的。 如果你这样部署Moqui,你必须使用外部的ElaticSearch服务器或集群。
对于一个Moqui本地开发实例,一个普通的开发周期是清理然后加载数据、运行测试、从已保存的归档中重加载数据并运行测试等。 要做一个全测试,确定ElasticSearch被安装在runtime/elasticsearch中并最好没有在运行,然后执行:
./gradlew loadsave test stopel
运行完后重新加载那些在初始数据加载后保存的数据(包括H2和ElasticSearch数据),并允许一个特定的组件测试(像mantel-usl),运行以下命令:
./gradlew reloadsave startel runtime:component:mantle-usl:test stopel
在通过各种方式运行完构建、加载等等之后,你会想启动Moqui并让它启动、停止ElasticSearch:
java -jar moqui.war
这些是在本地开发中一些常用例子,根据你喜欢的处理和Gradle任务可能会有不同。
8. 数据库和其他配置
环境变量
为了更易于Docker部署增加了对单数据库配置的支持,并且能被用在任意环境中。下一节介绍在Moqui运行时XML配置文件中增加数据库配置的方法。
每项都可以是系统环境变量(带下划线)或使用-D命令行参数指定的Java属性(带下划线或点)。
对应数据库的JDBC驱动必须放在类路径上。jar文件可被添加到runtime/lib目录(如果用了moqui-plus-runtime.war文件,则在war文件里面)或在命令行。 方便起见,在Docker镜像中容器内的runtime/lib目录(还有runtime/conf和许多其他目录)可被映射到主机上的目录。
注意'mysql'数据库配置也可以用在MariaDB和Percona。
环境变量或属性 | MySQL示例 | 描述 |
---|---|---|
entity_ds_db_conf | mysql | MoquiDefaultConf.xml或你添加的配置文件中的数据库配置项( |
entity_ds_host | localhost | 数据库服务器主机名 |
entity_ds_port | 3306 | 数据库端口 |
entity_ds_database | moqui | 数据库名称 |
entity_ds_schema | 数据库中使用的Schema (注: MySQL留空) | |
entity_ds_user | moqui | 数据库用户 |
entity_ds_password | CHANGEME | 数据库用户的密码 |
entity_ds_crypt_pass | CHANGEME | 被用于加密字段的密钥,应像密码一样保护好 |
entity_add_missing_startup | true | 对于MySQL默认为true,如果在启动时不增加缺失的表、字段则设置为false |
要配置打包到Moqui框架内的ElasticSearch客户端,使用以下环境变量:
环境变量或属性 | 示例 | 描述 |
---|---|---|
elasticsearch_url | http://localhost:9200 | ElasticSearch服务器的基准URL |
elasticsearch_user | ES服务器HTTP Basic 验证的用户名 | |
elasticsearch_password | ES服务器HTTP Basic 验证的密码 |
在使用预构建的包含runtime的WAR文件或者Docker镜像时,用环境变量是配置数据库的方便方法。
另一组用于组装URL、locale、时区等的常用环境变量:
环境变量或属性 | 示例 | 描述 |
---|---|---|
instance_purpose | production | 实例的目标。‘production’有特殊的含义。还有‘test’和‘dev’ |
webapp_http_host | moqui.org | 使用的主机名,默认为请求使用的主机名或IP地址 |
webapp_http_port | 80 | 非安全链接(http)的端口 |
webapp_https_port | 443 | 安全链接(https)的端口 |
webapp_https_enabled | true | 设置为true使用安全链接。默认为false,生成的所有链接使用非安全端口。 |
default_locale | en_US | |
default_time_zone | US/Pacific | |
database_time_zone | US/Pacific | 在数据库中使用的时区,默认与 default_time_zone 一致 |
scheduled_job_check_time | 60 | 检查规划任务执行的时间间隔(单位为秒),设置为0表示不允许规划的任务 |
Moqui配置XML文件
数据库(或数据源)设置在Moqui配置XML文件中用 moqui-conf.entity-facade.datasource 元素设置。 每个实体组对应有一个元素,datasource.@group-name 属性对应实体定义中的 entity.@group-name 属性。 Moqui中默认有4个实体组: transactional , nontransactional , configuration 和 analytical 。 如果你只为 transactional 组配置一个 datasource,那么它将被用于其他组。
下面是H2数据库的默认配置:
<datasource group-name="transactional" database-conf-name="h2" schema-name=""
start-server-args="-tcpPort 9092 -ifExists -baseDir ${moqui.runtime}/db/h2">
<!-- with this setup you can connect remotely using "jdbc:h2:tcp://localhost:9092/MoquiDEFAULT" -->
<inline-jdbc pool-minsize="5" pool-maxsize="50">
<xa-properties url="jdbc:h2:${moqui.runtime}/db/h2/MoquiDEFAULT" user="sa" password="sa"/>
</inline-jdbc>
</datasource>
database-conf-name 属性指向一个数据库配置,和 database-list.database.@name 对应。 数据库配置指定使用的SQL类型、SQL语法选项和JDBC驱动细节等。
此例使用一个 xa-properties 元素来使用JDBC驱动中的 XA (transaction aware)接口。元素上的属性对每个JDBC驱动都是特定的。 MoquiDefaultConf.xml中包含有一些参考例子,但所有选项的清单请查阅JDBC驱动的文档。
JDBC驱动必须在Java类路径中。适应所有部署方式的最简单的方法是把它放入 runtime/lib 目录。
这是一个MySQL XA配置的例子:
<datasource group-name="transactional" database-conf-name="mysql" schema-name="">
<inline-jdbc pool-minsize="5" pool-maxsize="50">
<xa-properties user="moqui" password="CHANGEME" pinGlobalTxToPhysicalConnection="true"
serverName="127.0.0.1" port="3306" databaseName="moqui" autoReconnectForPools="true"
useUnicode="true" encoding="UTF-8"/>
</inline-jdbc>
</datasource>
把 datasource 元素放在运行时Moqui配置XML文件(例如 MoquiProductionConf.xml )内的 entity-facade 元素下。
关于不同数据库的推荐配置的更多例子和细节,请查阅 MoquiDefaultConf.xml 文件 中的注释。
9. 生产环境推荐
Docker和Docker Compose
AWS Elastic Beanstalk 和 RDS
10. 项目目录结构
- moqui (from https://github.com/moqui/moqui)
- framework
- build : 框架构建的结果 (classes, jars, 等等)
- data : 种子数据
- entity : 框架实体定义
- lib : Moqui中使用的库 (JAR文件)
- screen : 框架界面
- service : 框架服务
- src : Java API, 标准 entities, services, data, XSDs, etc
- api : Moqui 框架API的 Java 源代码
- main : 主要的实现代码
- groovy : Groovy 源代码 (大部分实现)
- java : Java 源代码 (一些特殊的类)
- resources : 类路径资源,被原样放入JAR文件中
- webapp : 基础web应用,大部分只是一个WEB-INF/web.xml文件
- start : MoquiStart的Java 源代码, 被用于可执行WAR文件
- template : 框架模板 (界面/表单, xml-actions FTLs)
- xsd : 框架XML Schema 文件
- runtime
- base-component : 要部署的基础框架组件
- tools : 系统管理和维护工具
- webroot : 根界面和支持内容
- classes : 要加到运行时类路径的资源
- component : 要部署的应用等组件
- conf : 按dev, staging, prod等方式分离的配置文件
- db : H2, Derby, OrientDB等数据库的文件将放在这
- elasticsearch : 可选的 ElasticSearch 安装目录
- lib : 要加到运行时类路径的JAR文件
- log : 日志文件将放在这
- template : 通用模板
- tmp : 临时文件
- txlog : 事务日志文件将放在这 (Atomikos 或 Bitronix 文件)
放置你的组件的主要位置是runtime/component目录中。这也是你使用Gradle get component任务时它放组件的位置。
(在组件目录中component.xml中)声明依赖的组件,将在其依赖的组件之后加载。