该方法适用于maven构建的项目,自动部署需要用到maven插件wagon-maven-plugin
。
当配置插件后,部署流程如下:
- 客户端通过maven打包项目(package)
- 插件会自动将包上传到配置的服务器
- 插件调用wagon-ssh库执行部署脚本
上述流程中每次都需要手动操作的就只有第1条,其他都可以自动完成,这种方案很适用于开发过程中的测试部署,具体配置方法如下(想直接查看所有配置的代码见文末配置代码
)。
配置wagon-maven-plugin
配置wagon-maven-plugin分为4个部分:
- 配置服务器认证
- 配置插件执行阶段(
阶段
简单说就是插件的执行时机,比如package之后,可以搜索maven生命周期
关键词了解)。 - 配置上传包的目标(
目标
简单说就是要插件做的事情,一个插件可以做很多事情,一件事情就是一个目标) - 配置执行部署脚本目标
1. 配置服务器认证
在maven的配置文件settings.xml
(一般在用户目录下的.m2文件夹下)中配置服务器认证信息,即用户和密码,找到文件的大概121行可以看到配置server信息的注释,在注释后面添加如下代码。
1 | <server> |
其中,
- 标签
<id>
是该配置的唯一编号,后面配置插件连接服务器会用到,建议配置为服务器ip - 标签
<username>
是服务器登录用户名 - 标签
<password>
是服务器登录密码
2. 配置插件执行阶段
执行打包命令完成打包后,就要执行插件了,那么插件的执行时机就是package。pom.xml中新增如下代码。
1 | <plugin> |
其中,
- 标签
<execution>
表示定义执行,具体为后面要配置的上传包和执行部署脚本。 - 标签
<id>
表示这个执行的id,取一个有意义的名称即可。 - 标签
<phase>
表示这个插件在package阶段执行,即打包完成后执行。
简单描述下阶段以及如何配置插件在阶段中执行。比如命令mvn clean package
,这个命令中有2个阶段,即clean
和package
,如果想要pluginA插件在package之后执行,就可以执行命令mvn clean package pluginA
。如果希望命令简单一些,可以将插件的phase标签配置为package,这时候执行命令mvn clean package
就可以达到命令mvn clean package pluginA
同样的效果了。更多信息可以搜索maven生命周期关键词了解,不再赘述。
3. 配置上传包的目标
上传目标就是要插件将打好的包上传到服务器,需要配置:
- 服务器地址
- 上传到的路径
- 要上传的包的路径
配置服务器相关信息的代码如下,在<execution>
中加入<goals>
和<configuration>
标签。
1 | <plugin> |
其中,
- 标签
<goals>
表示目标,有多个目标时按照顺序执行,上传包使用upload-single
即可,即上传一次。 - 标签
<configuration>
表示服务器和上传路径配置
服务器和上传路径配置中,
- 标签
<serverId>
即上面配置的服务器认证的id。 - 标签
<fromFile>
表示打包后包的位置,一般都是target下的某个war包。 - 标签
<url>
表示使用scp将包拷贝到指定的路径,root 是服务器用户名,**@** 后面是服务器地址和存放路径(类似scp命令)。
4. 配置执行部署脚本目标
执行部署脚本目标是当包上传完成后,用于在服务器执行部署脚本的。具体配置如下,在<goals>
中加入<goal>
,即加入新的目标,多个目标按顺序执行。以及在<configuration>
标签中添加<commands>
和<displayCommandOutputs>
标签。
1 | <execution> |
其中,
- 标签
<goal>
表示执行ssh命令。 - 标签
<commands>
是要执行的命令行,具体命令在标签<command>
中。案列中是进入war包所在目录,然后执行run.sh脚本。 - 标签
<displayCommandOutputs>
表示在客户端打印出执行的命令和命令返回结果。
需要注意的是,commond标签中的命令涉及到目录或文件需要使用全路径,如果不想使用全路径,可以像案列中那样,多条命令用分号隔开合并为一条语句,后面的命令就可以使用相对路径了。
编写部署脚本
这个步骤就是自定义部署的命令了,比如解压war包到目录,重启docker等,当然也可以不通过sh文件执行,也可以在commond标签中直接写命令,但是每一行命令都要使用完整路径,否则就使用案列中的一条语句,多条命令用分号隔开。下面是一个sh脚本示例。
1 | date >> log.txt |
其他说明
wagon-maven-plugin版本说明
案列中采用的插件版本为2.0.0,如果使用1.0,还需要配置wagon-ssh
,否则无法正常执行命令,会报错Cannot find wagon which supports the requested protocol: sftp: java.util.NoSuchElementException
。
1 | <build> |
多个阶段执行命令
案列中将插件配置在package阶段执行,即打包后执行上传和部署,如果在打包之前还要做一些准备工作,比如清理之前的包,关闭容器等,那么可以再配置一个执行(execution)并在clean阶段执行即可,具体代码如下,在id为upload-and-deploy
这个执行之前再添加一个id为prepare
的执行,就可以在clean之后,package之前执行了。
1 | <plugin> |
FAQ
报错Cannot connect. Reason: invalid privatekey
错误原因是服务器认证没有配置或者配置不正确,配置方法见上述
配置服务器认证
。报错Cannot find wagon which supports the requested protocol: sftp: java.util.NoSuchElementException
错误原因是wagon-maven-plugin插件使用的1.0版本,并且没有配置
wagon-ssh
库,配置方法见上述wagon-maven-plugin版本说明
。
附件:配置代码
服务器认证配置
配置到maven的settints.xml中。
1
2
3
4
5<server>
<id>127.0.0.1</id>
<username>root</username>
<password>root</password>
</server>pom.xml配置
配置到pom.xml的plugins标签中。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>wagon-maven-plugin</artifactId>
<version>2.0.0</version>
<executions>
<execution>
<id>upload-and-deploy</id>
<phase>package</phase>
<goals>
<goal>upload-single</goal>
<goal>sshexec</goal>
</goals>
<configuration>
<serverId>127.0.0.1</serverId>
<fromFile>target/my-war-package.war</fromFile>
<url>scp://root@127.0.0.1/root</url>
<commands>
<command>cd /root;./run.sh</command>
</commands>
<displayCommandOutputs>true</displayCommandOutputs>
</configuration>
</execution>
</executions>
</plugin>