系统部署手册
针对window、linux部署进行描述
硬件环境
推荐选择云服务器,阿里云、百度云、腾讯云等都没问题。
服务器
推荐配置2核CPU/8G 内存/80G 硬盘
操作系统
window、linux
网络
最低要求1M
运行环境准备
最基本的系统运行环境,主要讲述java、tomcat、mysql
Java安装
下载安装包
自行从Oracle官网下载,下载地址:
https://www.oracle.com/java/technologies/downloads/

注:具备一定能力的用户也可以选择安装JRE
Tip
注意:在SpringBoot3版本以上需要JDK版本17以上
window安装
直接双击exe进行安装即可,安装完成后可以通过cmd指令验证是否安装成功。
java -version

如果没有正常显示对的java版本号,就需要进行环境变量配置,具体参考百度经验
https://jingyan.baidu.com/article/d45ad148ba5ab169552b80d3.html
linux安装
使用RPM包管理器安装JDK,首先将下载的JDK安装包复制到 /data,
# jdk-8u191-linux-x64.rpm 安装包名称,自行替换
rpm –ivh /data/jdk-8u191-linux-x64.rpm
Tomcat安装
下载安装包
推荐选择tomcat10
https://tomcat.apache.org/download-10.cgi

直接选择zip格式进行下载
Tip
在SpringBoot3版本以上需要Tomcat版本10及以上,jar部署不需要Tomcat。
在SpringBoot2版本使用Tomcat版本9及以下
window安装
tomcat直接解压就可以使用,

启动tomcat,直接双击startup.bat
linux安装
进入安装目录命令,通常安装在/usr/local目录下面
# 进入/usr/local目录
cd /usr/local
# 解压tomcat
tar –zxvf apache-tomcat-8.5.30.tar.gz
# 启动tomcat
/usr/local/apache-tomcat-8.5.30/bin/startup.sh
访问tomcat
tomcat端口默认8080,通过浏览器访问http://localhost:8080,出现tomcat表示成功。
Mysql安装
下载安装包
https://dev.mysql.com/downloads/mysql/
推荐安装8版本

选择对应操作系统版本安装包进行下载
window安装
1、去官网下载.zip格式的MySQL Server的压缩包,根据需要选择x86或x64版。
2、解压缩至你想要的位置。
3、复制解压目录下my-dafault.ini至bin目录下,重命名为my.ini。并添加以下内容(路径要根据实际的情况修改)
[mysql]
# 设置mysql客户端默认字符集
default-character-set=utf8
[mysqld]
#设置3306端口
port = 3306
# 设置mysql的安装目录(注意这里的路径)
basedir=C:\mysql-5.7.12-winx64
# 设置mysql数据库的数据的存放目录(注意这里的路径)
datadir=C:\mysql-5.7.12-winx64\data
# 允许最大连接数
max_connections=200
# 服务端使用的字符集默认为8比特编码的latin1字符集
character-set-server=utf8
# 创建新表时将使用的默认存储引擎
default-storage-engine=INNODB
4、初始化mysql
以管理员身份运行cmd,并cd到mysql中的bin目录下,执行命令:mysqld –initialize –user=mysql –console
该命令会创建data目录与数据库,生成root用户和临时密码,如下图
注意记下红框的随机密码,登录mysql需要使用
5、配置环境变量,否则你每次都要cd到bin目录下才能使用mysql。右键此电脑(计算机)-属性-高级系统设置-高级-环境变量,在系统变量中的PATH中加入你的bin目录,如:C:\mysql-5.7.12-winx64\bin
6、安装MySQL服务,以管理员身份运行cmd,并输入mysqld install MySQL –defaults-file=“C:\mysql-5.7.12-winx64\bin\my.ini”,其中的路径为你正式的ini文件。
7、运行cmd,输入net start mysql启动MySQL服务,再输入mysql -u root -p,然后输入临时密码。修改密码:set password = password(‘新密码’);,然后回车就可以了,注意分号不能省略。
linux安装(mysql 5.7版本)
1、卸载已有的mysql
# 查找所有与MySQL相关的包
rpm -qa | grep -i mysql
#停止mysql服务,卸载之前安装的mysql
rpm -ev 包名
#如果卸载过程中报依赖错误,直接在卸载命名后面加参数 --nodeps
rpm -ev 包名 --nodeps
#查找之前安装的mysql的文件,并逐个删除
find / -name mysql
2、开始安装
- 添加用户和组
# 创建 mysql 用户组
groupadd mysql
# 添加用户mysql 到用d户组mysql\(使用-r参数表示mysql用户是一个系统用户,不能登录\)
useradd -r -g mysql mysql
- 手动创建MySQL data目录
cd /usr/database/mysql5.7/
mkdir data
# 目录权限设置
# 将mysql及其下所有的目录所有者和组均设为mysql
chown -R mysql:mysql /usr/database/mysql5.7/
3、配置my.cnf文件
此文件非常重要,初始化之前要把此文件放到 /etc 目录下
rm -rf /etc/my.cnf
vim /etc/my.cnf
#此文件内容如下\(路径根据自己的实际情况\):
[client]
port = 3306
socket = /tmp/mysql.sock
[mysqld]
init-connect='SET NAMES utf8'
basedir=/usr/database/mysql5.7 #根据自己的安装目录填写
datadir=/usr/database/mysql5.7/data #根据自己的mysql数据目录填写
socket=/tmp/mysql.sock
max_connections=200 # 允许最大连接数
character-set-server=utf8 # 服务端使用的字符集默认为8比特编码的latin1字符集
default-storage-engine=INNODB # 创建新表时将使用的默认存储引擎
4、初始化mysql
/usr/database/mysql5.7/bin/mysqld --initialize-insecure --user=mysql --basedir=/usr/database/mysql5.7 --datadir=/usr/database/mysql5.7/data
#重新修改下各个目录的权限
#把安装目录的目录的权限所有者改为root
chown -R root:root /usr/database/mysql5.7/
#把data目录的权限所有者改为mysql
chown -R mysql:mysql /usr/database/mysql5.7/data/
Tip
注意:mysqld –initialize-insecure初始化后的mysql是没有密码的
5、启动mysql
/usr/database/mysql5.7/bin/mysqld_safe --user=mysql &
6、修改密码
cd /usr/database/mysql5.7/bin/
# 默认没有密码,直接敲回车就可以
./mysql -u root -p
use mysql;
update user set authentication_string=password('这里填你设置的密码') where user='root';
flush privileges;
exit;
7、测试登录
cd /usr/database/mysql5.7/bin/
./mysql mysql -u root -p
#输入密码后,应该就连接上了
show databases;
exit;
8、copy启动脚本并将其添加到服务
#mysql启动脚本为:
/usr/database/mysql5.7/support-files/mysql.server
cp /usr/database/mysql5.7/support-files/mysql.server /etc/init.d/mysql
#添加服务
chkconfig --add mysql
9、开机启动
chkconfig --level 345 mysql on
# 测试添加的服务是否能用
#查看状态
service mysql status
#启动mysql服务
service mysql start
#停止mysql服务
service mysql stop
10、设置外网可以访问
#在mysql的bin目录下执行,连接数据库:
mysql -uroot -p密码
use mysql;
select host,user from user;
update user set host='%' where user ='root';
flush privileges;
发布部署
-
修改数据库连接 src\main\resources\application-dev.yml
-
后台登录路径
src\main\resources\application.yml
manager:
path: /ms
docker部署
安装docker
Debian\UOS\Ubuntu
#更新系统
sudo apt update
#安装docker-ce
sudo apt install docker-ce
CentOS
#更新系统
sudo yum update
#安装docker-ce
sudo yum install docker-ce
Tip
如果
docker-ce安装提示不存在包,可以安装docker-io
一般安装好系统建议更换镜像源为国内地址,后面安装软件下载速度会快很多。如果docker安装软件下载很慢,可以更换国内镜像库,参考博文
- docker 国内镜像配置
#编辑docker配置文件
sudo vi /etc/docker/daemon.json
#增加下面json 配置
{
"registry-mirrors": ["https://ha0sig3m.mirror.aliyuncs.com"]
}
容器配置
创建统一的docker挂载目录,具体路径根据实际情况可以修改
#mysql文件,容器会自动生成
sudo mkdir /data/mysql
#复制打包好的jar包与项目文件夹
sudo mkdir /data/mcms
#代理配置
sudo mkdir /data/nginx
Tip
挂载目录常存放配置文件或常更新的文件,避免容器损坏导致数据文件或配置丢失
Docker网络
#创建docker网络,方便固定docker容器ip
sudo docker network create --opt com.docker.network.driver.mtu=1450 \
--opt com.docker.network.bridge.name=docker1 --subnet=172.18.0.1/16 ms
Tip
创建docker网络,并给容器设置docker网络ip后;如遇到自启动容器没有启动,比如mysql、portainer、nginx等一些设置restart=always的容器,请优先重启虚拟机
安装portainer
sudo docker run --name portainer --network=ms --ip 172.18.0.98 -p 9000:9000 -d \
--restart=always -v /var/run/docker.sock:/var/run/docker.sock portainer
Tip
方便管理docker容器,不需要指令管理docker
安装MySQL
sudo docker run --network=ms --ip 172.18.0.3 --name mysql \
-e TZ="Asia/Shanghai" \
-p 3306:3306 \
--privileged=true --restart=always -e MYSQL_ROOT_PASSWORD=root -d mysql:5.7 \
--sql-mode="STRICT_TRANS_TABLES,NO_ENGINE_SUBSTITUTION" \
--lower-case-table-names=1 \
--symbolic-links=1 \
--skip-name-resolve=0 \
--max-connections=1000
Tip
建议使用目录挂载
-v /data/mysql/:/var/lib/mysql避免容器删除导致数据也删除,
挂载具体操作步骤:
1、通过上面的脚本创建创建一个初始化容器
2、通过sudo docker cp mysql:/var/lib/mysql /data/将mysql初始化的数据库文件复制到宿主机
3、通过portainer管理工具删除刚创建好的mysql容器,
4、再执行上面的脚本,注意:需要增加-v /data/mysql/:/var/lib/mysql目录挂载开启远程
root登录步骤:
1、通过portainer进入mysql容器指令维护模式
2、登录mysql -uroot -p,密码初始为root,
3、执行alter user 'root'@'%' identified with mysql_native_password by 'root';
(MySQL 8 使用ALTER USER 'root'@'%' IDENTIFIED WITH caching_sha2_password BY 'root';)
4、刷新权限flush privileges;
5、本地通过数据库连接工具连接上mysql,
安装MCms
需要先将 mcms 打包好的文件上传到 /data/mcms 目录下,具体目录结构参考下图:

x86 脚本
#springboot2版本
docker run --name mcms -v /data/mcms:/home -w /home \
--network=ms --ip 172.18.0.50 -p 8080:8080 \
--privileged=true mingsoft/java \
java -jar mcms.jar
#springboot3版本
docker run --name mcms -v /data/mcms:/home -w /home \
--network=ms --ip 172.18.0.50 -p 8080:8080 \
--privileged=true docker.1ms.run/openjdk:17-jdk \
java -jar mcms.jar
arm64 脚本
docker run --name mcms -d -v /data/mcms:/home -w /home \
--network=ms --ip 172.18.0.50 -p 8080:8080 \
-w /home --restart=always --privileged=true \
arm64v8/openjdk \
java -jar mcms.jar
Tip
记得修改
config目录下的数据库连接配置,数据库的ip地址为mysql容器的ip地址,如:上面mysql脚本的ip为172.18.0.3
安装Nginx
#注意:根据实际情况挂载mcms的运行目录,方便nginx实现文件代理
docker run --name nginx -d \
--network=ms --ip 172.18.0.10 -p 80:80 \
--restart=always --privileged=true \
docker.io/nginx
Tip
建议挂载
-v /data/nginx:/etc/nginx避免容器删除导致配置丢失,
挂载具体操作步骤:
1、通过上面的脚本创建创建一个初始化容器
2、通过sudo docker cp nginx:/etc/nginx /data/
3、通过portainer管理工具删除刚创建好的nginx容器,
4、再执行上面的脚本,注意:需要增加-v /data/nginx:/etc/nginx目录挂载
nginx.conf配置
参考 Nnginx代理配置 章节
jar部署
打包方式
将所有的资源打成一个jar包
pom.xml
<resources>
<resource>
<directory>src/main/webapp</directory>
<!--打包排除文件夹配置-->
<excludes>
<!-- 打包生产并手动将static、html、upload、template复制到生产 -->
<exclude>static/</exclude>
<exclude>html/</exclude>
<exclude>upload/</exclude>
<exclude>template/</exclude>
<!-- 如果生产需要实时修改WEB-INF/下的页面可,启用这行并手动将项目中的WEB-INF目录复制到运行环境 -->
<!-- <exclude>WEB-INF/</exclude>-->
</excludes>
</resource>
<resource>
<directory>src/main/resources</directory>
</resource>
<resource>
<directory>src/main/java</directory>
<excludes>
<exclude>**/*.java</exclude>
</excludes>
</resource>
</resources>
mvn clean package
Tip
根据pom.xml文件中的resource节点中的提示,可以灵活控制需要打包的文件夹目录。
多模块打包
- 在ms-mcms 模块 pom.xml 文件中排除静态资源(参考上述配置),推荐排除WEB-INF,方便生产需要实时修改WEB-INF/下的页面
- 在ms-parent 模块 package 打包
- 部署时只需要ms-mcms 模块的jar包
- 其他参考下方的目录结构创建文件
目录结构
只需要在ms-mcms模块操作,完成下面目录结构后,
在当前文件夹进入cmd执行命令
java -jar ms-mcms.jar

config:配置文件,会优先使用config文件夹下的配置(需手动创建,手动复制src/main/resources/*下的配置文件)
WEB-INF:ftl视图文件
template:(必须)模版目录,需要复制一份
upload:(必须)上传的文件夹
html:静态化自动生成的目录(自动生成)
static:静态资源文件
ms-mcms.jar:主程序
*.sh:linux启动、停止脚本(手动复制bin下脚本,docker不需要此脚本)
*.bat:window启动、停止脚本(手动复制bin下脚本,docker不需要此脚本))
Tip
推荐docker容器部署,方便维护。docker部署也可以参考此目录机构方式,方便灵活更新系统文件,启动脚本参考 开源中国
war部署
打包方式
修改pom.xml
....
<name>ms-mcms</name>
<!-- 打包war包 -->
<packaging>war</packaging>
....
mvn clean package
部署
linux
1.将打包好的war包放进Tomcat的webapps下
2.修改Tomcat bin 目录下的catalina.sh,添加一行修改语言和时区的脚本
# OS specific support. $var _must_ be set to either true or false.
export JAVA_OPTS="$JAVA_OPTS -Duser.timezone=Asia/shanghai -Duser.language=zh -Duser.region=CN"
3.执行bin 目录下的startup.sh启动项目
Tip
注意:在SpringBoot3版本以上需要Tomcat版本10以上
window
1.将打包好的war包放进Tomcat

Important
如果本地开发没有使用项目名context-path,且没有项目名需求,需要把xxx.war重命名为ROOT.war,并删除ROOT文件夹,否则会多一层访问路径导致资源404
2.点击startup.bat启动项目,默认生成的日志文件mcms.log

Important
如果是通过ningx+tomcat的方式部署,需要修改
tomcat的server.xml的Host的域名,否则会出现静态化之后,页面会出现错误的url地址127.0.0.1,application.yml 里面配置的端口必须与 tomcat(或其他容器)端口一致
国产中间件
国产中间件通常是打包war包的方式部署,开发者直接根据pom.xml的注释引导信息导出war包,
Tip
第一次部署war成功之后,以后更新服务器就直接通过文件覆盖的方式更新对应的文件夹,不需要每次都部署war包的方式,否则会出现文件被覆盖的情况;如果非得要每次war部署,那建议部署前先把静态文件先备份一下。等war部署好后再覆盖还原这些进来文件夹。
重点!!!
Warning
如果部署失败第一时间连接中间件供应商,基本都有正确的解答,必要的时候请求远程调试;
包加载顺序(老版本之前会打包有ms-mcms-co的包就采用这个顺序配置,还有使用站群插件也需要这样配置)
因为war包部署时候存在一个jar包加载顺序的问题,需要手动修改lib目录下的jar包名称,主要目的控制jar包在容器中的加载顺序,让jar包中重写的代码生效,只需要在jar包文件名称前面增加a、b、c字符来调整顺序即可,具体的根据pom.xml的顺序一致;

<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-war-plugin</artifactId>
<configuration>
<!-- 排除多个需要解压的 JAR 包 -->
<packagingExcludes>
WEB-INF/lib/ms-site.jar,
WEB-INF/lib/ms-module-a.jar,
WEB-INF/lib/ms-module-b.jar
</packagingExcludes>
<overlays>
<!-- 按顺序定义 overlays,后面的会覆盖前面的 -->
<!-- 第一个 overlay:基础模块(优先级最低) -->
<overlay>
<groupId>net.mingsoft</groupId>
<artifactId>ms-module-a</artifactId>
<type>jar</type>
<targetPath>WEB-INF/classes</targetPath>
<includes>
<include>**/*.class</include>
</includes>
</overlay>
<!-- 第二个 overlay:中间模块 -->
<overlay>
<groupId>net.mingsoft</groupId>
<artifactId>ms-module-b</artifactId>
<type>jar</type>
<targetPath>WEB-INF/classes</targetPath>
<includes>
<include>**/*.class</include>
</includes>
</overlay>
<!-- 第三个 overlay:ms-site(优先级最高,会覆盖前面的) -->
<overlay>
<groupId>net.mingsoft</groupId>
<artifactId>ms-site</artifactId>
<type>jar</type>
<targetPath>WEB-INF/classes</targetPath>
<includes>
<include>**/*.class</include>
</includes>
<!-- 可以添加其他资源文件 -->
<includes>
<include>**/*.xml</include>
<include>**/*.properties</include>
</includes>
</overlay>
</overlays>
</configuration>
</plugin>
Tip
推荐jar包方式部署,jar部署方式基本可以与本地开发运行效果一直
Nginx代理配置
主要的配置参考
...
server {
listen 80;
#ipv6配置
listen [::]:80;
#根据实际地址配置
server_name www.mingsoft.net;
#mcms所在的目录 根据实际部署mcms所在目录配置
root /data/mcms;
#启用ssl,去掉#注释
#listen 443 ssl http2;
#set $flag 0;
#if ($server_port !~ 443){
# set $flag "${flag}1";
#}
#if ($request_method !~ ^(POST)$) {
# set $flag "${flag}1";
#}
#if ($flag = "011"){
# rewrite ^(/.*)$ https://$host$1 permanent;
#}
#ssl_certificate mcms.pem;
#ssl_certificate_key mcms.key;
#ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
#ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:HIGH:!aNULL:!MD5:!RC4:!DHE;
#ssl_prefer_server_ciphers on;
#ssl_session_cache shared:SSL:10m;
#ssl_session_timeout 10m;
location / {
index default.html default.htm index.html index.htm;
rewrite / /msIndex.do;
}
location ~ .*\.(do)$ {
# 根据实际系统启动等地址配置
proxy_pass http://127.0.0.1:8080;
# 注意:如果使用了堡垒机端口映射,例如:映射端口8989 -> nginx端口80 -> mcms端口8080,需要将mcms端口8080修改成8989,如果遇到访问地址不正确,可以将$host:$server_port直接填写外网ip或域名与端端口(必须与实际端口一致)
#proxy_set_header Host $host:$server_port;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
add_header Access-Control-Allow-Origin $http_origin;
add_header Access-Control-Allow-Credentials true;
}
#代理jar包里面的js,如果遇到其他jar包按规则配置(也可以直接将资源文件复制到static目录-推荐)
location ~ /(static/mdiy|static/mweixin|static/datascope) {
# 根据实际系统启动等地址配置
proxy_pass http://127.0.0.1:8080;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
add_header Access-Control-Allow-Origin $http_origin;
add_header Access-Control-Allow-Credentials true;
}
# 代理静态资源中的html,防止转发错误
location ~ ^/static/.*\.html$ {
root /data/mcms;
expires 24h;
}
#一台服务器实现动静分离效果
location ~ .*\.(html)$ {
#具体根据实际项目情况配置路径,开启了断链接必须 后面加 html路径 如:root /data/mcms/html
root /data/mcms;
expires 24h;
}
#静态资源,
location ~ /(static/plugins|html|upload){
#缓存(天)
expires 12d;
}
location ~ .*\.(gif|jpg|jpeg|png|css|js|html|htm|eot|otf|ttf|woff|woff2|svg|less)$ {
expires 24h;
}
#屏蔽
location ^*/WEB-INF/ {
deny all;
}
access_log /var/log/nginx/mcms.log;
}
...
Tip
根据实际的域名进行配置调整(mcms所在的目录位置、服务器mcms文件夹结构、nginx非80端口),
注意:如果配置不正确会导致例如百度编辑器上传错误、404等问题
单机端口动静分离部署配置
...
http {
server {
listen 80;
server_name localhost;
#mcms jar所在的目录 根据实际部署mcms所在目录配置
root /data/mcms;
#短链接首页配置 首页文件预期路径 /data/mcms/html/default(index).htm(l)
location / {
root /data/mcms/html;
index default.html default.htm index.html index.htm;
}
#长链首页配置 首页文件预期路径 /data/mcms/html/web/default(index).html
#location = / {
# try_files /html/web/default.html /html/web/index.html =404;
#}
#一台服务器实现动静分离效果
location ~ .*\.(html)$ {
#具体根据实际项目情况配置路径,开启了短链接需要指定root,长链接不需要
root /data/mcms/html;
expires 24h;
}
# 文章访问点击数接口代理配置示例 其余接口按需增加代理
location ~ ^/cms/content/(\d+)/hit\.do$ {
# 根据实际系统启动等地址配置
proxy_pass http://127.0.0.1:8080$request_uri;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
#代理jar包里面的js,如果遇到其他jar包按规则配置(也可以直接将资源文件复制到static目录-推荐)
location ~ /(static/mdiy|static/mweixin|static/datascope) {
# 根据实际系统启动等地址配置
proxy_pass http://127.0.0.1:8080;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
add_header Access-Control-Allow-Origin $http_origin;
add_header Access-Control-Allow-Credentials true;
}
#静态资源,
location ~ /(static/plugins|html|upload){
#缓存(天)
expires 12d;
}
location ~ .*\.(gif|jpg|jpeg|png|css|js|html|htm|eot|otf|ttf|woff|woff2|svg|less)$ {
expires 24h;
}
location ^*/WEB-INF/ {
deny all;
}
}
server {
listen 8088;
server_name localhost;
#mcms所在的目录 根据实际部署mcms所在目录配置
root /data/mcms;
location / {
index default.html default.htm index.html index.htm;
rewrite / /msIndex.do;
}
location ~ .*\.(do)$ {
# 根据实际系统启动等地址配置
proxy_pass http://127.0.0.1:8080;
# 注意:如果使用了堡垒机端口映射,例如:映射端口8989 -> nginx端口80 -> mcms端口8080,需要将mcms端口8080修改成8989,如果遇到访问地址不正确,可以将$host:$server_port直接填写外网ip或域名与端端口(必须与实际端口一致)
#proxy_set_header Host $host:$server_port;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
add_header Access-Control-Allow-Origin $http_origin;
add_header Access-Control-Allow-Credentials true;
}
#代理jar包里面的js,如果遇到其他jar包按规则配置(也可以直接将资源文件复制到static目录-推荐)
location ~ /(static/mdiy|static/mweixin|static/datascope) {
# 根据实际系统启动等地址配置
proxy_pass http://127.0.0.1:8080;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
add_header Access-Control-Allow-Origin $http_origin;
add_header Access-Control-Allow-Credentials true;
}
#一台服务器实现动静分离效果
location ~ .*\.(html)$ {
#具体根据实际项目情况配置路径,开启了断链接必须 后面加 html路径 如:root /data/mcms/html
root /data/mcms/html;
expires 24h;
}
#静态资源,
location ~ /(static/plugins|html|upload){
#缓存(天)
expires 12d;
}
location ~ .*\.(gif|jpg|jpeg|png|css|js|html|htm|eot|otf|ttf|woff|woff2|svg|less)$ {
expires 24h;
}
#屏蔽
location ^*/WEB-INF/ {
deny all;
}
}
}
多台服务器动静分离部署配置(静态页面服务器)
如果是将静态文件同步到独立的服务器访问,只需要部署nginx不需要部署mcms的配置
...
server {
listen 80;
#ipv6端口80
listen [::]:80;
#根据实际地址配置
server_name www.mingsoft.net;
#如果只是代理生成好的静态文件,同时需要将template、upload、static同步到服务器
root /data/mcms/html/站点目录;
location / {
index default.html default.htm index.html index.htm;
}
#静态资源
location ~ /(static/plugins|html|upload|template){
#缓存(天)
expires 12d;
}
location ~ .*\.(gif|jpg|jpeg|png|html|htm|css|js)$ {
expires 24h;
}
#屏蔽
location ^*/WEB-INF/ {
deny all;
}
access_log /var/log/nginx/mcms.log;
}
...
多模板配置示例
data目录结构示例
data/
├── html/
│ ├── out/
│ │ ├── index.html
│ │ └── ...
│ └── default/
│ ├── index.html
│ └── ...
│
├── static/
│
├── template/
│ └── 1/
│ ├── out/
│ └── default/
│
└── upload/
server {
listen 80;
#如果只是代理生成好的静态文件,同时需要将template、upload、static同步到服务器 /data 目录下
root /data;
# 首页配置
location = / {
# 直接返回首页文件
root /data/html/default;
try_files /index.html =404;
}
location / {
index default.html default.htm index.html index.htm;
root /data/html;
}
#一台服务器实现动静分离效果
location ~ .*\.(html)$ {
#具体根据实际项目情况配置路径,开启了短链接必须 后面加 html路径 如:root /data/mcms/html
root /data/html;
expires 24h;
}
#静态资源
location ~ /(static/plugins|html|upload|template){
#缓存(天)
expires 12d;
}
#支持访问的文件类型
location ~ .*\.(gif|jpg|jpeg|png|html|htm|css|js|json)$ {
expires 24h;
}
#屏蔽
location ^*/WEB-INF/ {
deny all;
}
access_log /var/log/nginx/mcms.log;
}
Tip
采用这种方式部署时,建议模版里面的路径都采用相对的路径,不要使用
{ms:global.url/}或{ms:global.host/}标签,这样生成的html就不会存在域名的信息,方便静态文件的部署。如果使用了站群情况下需要对每个站点域名配置对应的server
Tip
采用分离部署时,需要将后台服务产生的新html页面同步到静态服务中,通过服务器的文件同步配置
脚手架版本配置
实际脚手架部署会部署两个地址,例如:http://admin.域名 访问脚手架管理后台,http://域名 访问MCms静态化后的页面。
如果脚手架文件与项目使用同一个域名下访问时候,需要将脚手架的访问路径增加一层目录,如:http://域名/admin/访问脚手架页面,http://域名 访问MCms静态化后的页面。
如果MCms设置了 server.servlet.context-path,需要将脚手架的 VITE_PROXY 值与 server.servlet.context-path 一致,
#增加资源的代理
location ~ ^/(static|upload|template)/ {
# 根据实际系统启动等地址配置
proxy_pass http://127.0.0.1:8080;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
add_header Access-Control-Allow-Origin $http_origin;
add_header Access-Control-Allow-Credentials true;
}
常见问题
主机头注入攻击

不安全、不正确、缺少SameSite的Cookie

trace、track http不安全、不安全的option http

配置Content-Security-Policy

配置x-content-type-options

配置Referral Policy Security

跨站脚本攻击

跨站点请求伪造

宝塔部署
步骤
- 打包mcms 参考jar部署,也可以选择一键运行版本直接使用
- 上传到服务器
- 终端通过指令启动
Tip
下面以linux一键版本为例
上传文件

通过宝塔文件管理功能将linux一键版本上传到服务器,
Tip
源码打包的直接将打包后的文件上传到服务器
终端启动
进入终端
通过宝塔终端方式启动 MCms,
文件同步
https://pkgs.org/download/inotify-tools
如果遇到notify-tools 无法通过指令安装时,可以下载对应的操作系统版本进行安装
主服务器
- 实时同步
sudo yum -y install notify-tools
- 同步账号
sudo echo "123456" > /etc/rsyncd.secrets
sudo chmod 600 /etc/rsyncd.secrets
#用那个用户权限启动,对应的文件必须当前用户一致
sudo chown root:root /etc/rsyncd.secrets
- 同步脚本
sudo vim inotify.sh
#!/bin/bash
#监听文件变化
INOTIFY_CMD="inotifywait -mrq -e modify,create,attrib,move,delete /home/mcms/"
$INOTIFY_CMD | while read DIRECTORY EVEVT FILE
do
#同步文件
rsync -azH --delete --password-file=/etc/rsyncd.secrets --exclude-from=/home/ceshi/Soft/sh/exclude.list /home/mcms/ rsync@172.16.1.95::mcms
done
- exclude.list 格式
*.yml
*.jar
- 后台启动
sudo sh ./inotify.sh&
- 停止
sudo ps -ef | grep inotify | grep -v "grep" | awk '{print $2}' | xargs sudo kill -9
从服务器
- 同步账号
sudoecho"rsync:123456" > /etc/rsyncd.secrets
- 同步配置
sudo vim /etc/rsyncd.conf
uid = root
gid = root
use chroot = no
max connections = 2
pid file = /var/run/rsyncd.pid
log file = /var/log/rsyncd.log
lock file = /var/run/rsyncd.lock
[mcms]
path = /home/mcms
read only = no
auth users = rsync
secrets file = /etc/rsyncd.secrets
list = no
- 启动同步
sudo rsync --daemon
- 重启同步
sudo rm /var/run/rsyncd.pid
ps -ef | grep rsync | grep -v grep |awk '{print $2}'| xargs sudo kill -9
常见问题
打包发布流程
前提确保ide中运行正常后,打jar(war)包
本地自检
本地按照部署文档目录结构部署jar(war)包,运行自检效果是否和ide中一致
-
效果不一致
请检查本地部署目录结构是否和文档一致,配置文件、模板文件等是否和ide中一致;此处一般是因为文件和ide中不一致
线上部署
本地部署运行正常后,按照本地的结构部署到线上
-
启动失败
一般是因为配置文件未同步导致;具体需要结合日志分析
-
启动成功,但某些功能异常
本地部署正常运行,一般说明jar(war)包是正常的;根据异常的功能和日志进行排查分析,可能触发的原因,如服务器环境、服务器文件读写权限、防火墙等等
部署后,模板编辑、自定义标签修改等功能异常
场景描述:本地修改模板、修改自定义标签数据都正常,但是部署到线上后发现功能异常;
问题体现:无法编辑保存,浏览器控制台有请求错误,但后台没有请求日志,没有接收到请求

这种问题一般都是由于部署环境有waf之类的安全拦截,模板、标签的内容触发了服务器安全拦截,优先检查服务器配置
国产服务器部署登录失败
控制台提示vue3-sfc-loader资源相关错误
通常都是因为浏览器不支持新JS特性导致,处理方案
-
升级浏览器版本
-
降低资源版本
获取资源,将现在的资源覆盖

docker网络故障导致系统无法访问
docker网络不通,优先尝试重启虚拟机。

打包发布服务器依赖包里面的js文件404
采用nginx代理静态资源的时候通常会映射到具体的某个目录,需要手动将依赖包的js文件复制到静态目录文件夹下。或者单独的增加一条js映射例如:自定义包里面的 index.js 文件
location ~ /(static/mdiy) {
proxy_pass http://localhost:8080;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
add_header Access-Control-Allow-Origin $http_origin;
add_header Access-Control-Allow-Credentials true;
}
如果没有采用nginx代理,可能是打包问题,必须要在父工程ms-parent进行打包
内网环境如何搭建多站点的站群环境
需要配合ng代理实现,利用ng监听不同端口,代理到服务的真实端口,例如:(详细配置参考发布部署-nginx代理配置)
···
server {
listen 8081;
···
location / {
# 根据实际系统启动等地址配置
proxy_pass http://127.0.0.1:5108;
# 注意:如果使用了堡垒机端口映射,例如:映射端口8989 -> nginx端口80 -> mcms端口8080,需要将mcms端口8080修改成8989,如果遇到访问地址不正确,可以将$host:$server_port直接填写外网ip或域名与端端口(必须与实际端口一致)
proxy_set_header Host $host:$server_port;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
add_header Access-Control-Allow-Origin $http_origin;
add_header Access-Control-Allow-Credentials true;
}
···
}
server {
listen 8082;
···
location / {
# 根据实际系统启动等地址配置
proxy_pass http://127.0.0.1:5108;
# 注意:如果使用了堡垒机端口映射,例如:映射端口8989 -> nginx端口80 -> mcms端口8080,需要将mcms端口8080修改成8989,如果遇到访问地址不正确,可以将$host:$server_port直接填写外网ip或域名与端端口(必须与实际端口一致)
proxy_set_header Host $host:$server_port;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
add_header Access-Control-Allow-Origin $http_origin;
add_header Access-Control-Allow-Credentials true;
}
···
}
···
部署后,验证码问题
Tip
规范: 验证码请求路径使用需添加 .do,如/code?t=改成/code.do?t=
登录页面验证码不显示报java.lang.NullPointerException at sun.awt.FontConfiguration.getVersion(FontConfiguration.java:1264)
安装fontconfig更新字体缓存
参考博文
验证码始终提示错误
- 部署没有将头信息进行代理导致
- 如果是分布式部署,需要自行二次开发增加会话共享机制,参考博文
静态资源更新问题
修改css、js静态资源等静态资源后,访问发现静态资源没更新
-
清空访问的静态资源,重新访问,确定访问的资源路径正确
-
请求资源后,按住shift刷新
-
请求静态资源后拼接参数,让浏览器重新请求资源
-
如果使用了国产中间件,需要在中间件中修改配置,具体修改需要中间件厂商配合
Tip
示例 如在金蝶中,需要修改domains/mydoamin/config下的apusic.conf,修改<ATTRIBUTENAME=“ServletReloadcheckInterval“VALUE=”-1“/>,value修改为需要生效的时间;
生产上线后需要关闭,会占用服务器资源;
nginx部署,上传图片时提示Request Entity Too Large 状态码413
按需配置 client_max_body_size
通过nginx 配置后 css和js文件 403 无法访问
一般是文件权限与nginx的启动用户权限不一致导致,最简单的方法是直接将nginx 启动用户修改为 root 启动
多服务共享模板和静态文件
使用rsync或者做共享,文件服务能达到共享就行 如nfs、fastdfs
jar包部署好模板无法上传、百度编辑器显示配置错误

- 执行指令需要在jar的当前目录执行
- 确保yml中ms.upload.enable-web的配置为true
- 确保部署的资源(static、upload、template)与jar在同一级,可参考部署文档的资源结构
- nginx 配置
location / {
proxy_pass http://localhost:8080;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
location ~ .*\.(do|jsp|index)$ {
proxy_pass http://localhost:8080;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
#静态资源、生成的页面、上传的文件、模板目录
location ~ /(static|html|upload|templets){
#缓存时间 7天
expires 7d;
#项目部署位置,当前项目部署在/home/mcms
root /home/mcms;
}
打包jar包运行时百度编辑器错误
将static目录复制到jar包同级目录

缓慢http拒绝服务攻击
参考: https://www.cnblogs.com/wsx2019/p/17611226.html
CORS跨域问题
参考: https://zhuanlan.zhihu.com/p/661237362
html/1伪静态处理
1、配置nginx ,将所有的.html 映射到 项目/html/1文件夹
2、将模版里面所有链接去掉{ms:global.url/}标签
https访问问题
使用springboot加证书的方式访问没有问题,如果用nginx代理访问时,{ms:global.host/}标签解析后还是http的形式,可以将模版资源采用//的方式,例如:
<script src="//mingsoft.net/xxx.js"/>
${field.hit}失效
需要将field.hit的请求进行代理,/cms/content/文章id/hit.do
登录验证码输入错误,报文件找不到
资源文件读取报错,Linux默认读取en的资源文件,导致未找到该文件,可以在java启动的指令配置服务cn 的资源文件
docker run --name mcms -d -v /home/mcms:/home -p 8080:8080 -w /home \
--restart=always --privileged=true store/oracle/serverjre:8 java \
-Duser.timezone=GMT+08 -Duser.language=zh \
-Duser.region=CN \
-Dspring.config.location=/home/application.yml,/home/application-dev.yml \
-jar mcms.jar
数据库的时间对不上,少了8个小时
java 启动配置时区-Duser.timezone=GMT+08
docker run --name mcms -d -v /home/mcms:/home -p 8080:8080 -w /home \
--restart=always --privileged=true store/oracle/serverjre:8 java \
-Duser.timezone=GMT+08 -Duser.language=zh -Duser.region=CN \
-Dspring.config.location=/home/application.yml,/home/application-dev.yml \
-jar mcms.jar
管理页面WEB-INF/manger单独配置在jar外面,修改部分ftl避免重新jar打包
修改: application.yml template-loader-path
template-loader-path: file:WEB-INF/,file:WEB-INF/manager,classpath:/,classpath:/WEB-INF/manager,classpath:/WEB-INF

Tomcat部署路径问题
-
tomcat部署会多一层路径,默认多的路径为war包名称
-
tomcat可以放到root下,避免多一层路径
Tomcat部署驱动加载问题
如果遇到tomcat启动不加载驱动问题,可以手动把驱动放到lib包下
Tomcat启动war包没有看到日志信息
默认在Tomcat启动脚本目录,application.yml中logging.file.name参数可按需配置
宝兰德部署启动解不开war包
检查war包中是否包含web.xml文件,如果有需要手动解压到部署目录并且删除web.xml文件,在打包时需排除tomcat依赖。
Tip
部署后出现部分页面404,若tomcat下运行没有问题本质上也是大概率这些原因
log 打印文件未找到
1.war包使用Tomcat启动,默认log文件在(当前执行指令目录)bin目录

可修改log文件路径

2.jar包log文件在当前执行java指令目录,避免全部在jar同级目录可自行配置目录


东方通部署
编码问题
需要在 HTTP通道管理 中设置URL编码格式为UTF-8

页面访问404
需要把项目中的WEB-INF/web.xml删除掉
金蝶部署
- 打包方式修改为war
- 排除spring-boot-start-web自带的tomcat依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<!--移除内嵌tomcat-->
<exclusions>
<exclusion>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
</exclusion>
</exclusions>
</dependency>
- 添加Servlet依赖
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>3.1.0</version>
<scope>provided</scope>
</dependency>
- 修改入口方法
@SpringBootApplication
public class MSApplication extends SpringBootServletInitializer {
public static void main(String[] args) {
SpringApplication.run(MSApplication.class, args);
}
@Override
protected SpringApplicationBuilder configure(SpringApplicationBuilder builder) {
return builder.sources(MSApplication.class);
}
}