Automagically deploy your web application using the Maven Cargo plugin.

Last week I optimized the deployment process of a number of Mavenized projects. I noticed that the way I automated the project was not yet (fully) known by the developers. This is why I decided to write this blogpost.

It appeared to be a true eyeopener for the developers.

This example assumes that you have a local instance of Apache Tomcat 7.x running.

First, create a new project using Maven:

mvn archetype:create -DgroupId=nl.redstream.demo
                     -DartifactId=simplewebapp
                     -DarchetypeArtifactId=maven-archetype-webapp

Add the Cargo plugin to the pom.xml (inside the <build> tag)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
<plugins>
    <plugin>
        <groupId>org.codehaus.cargo</groupId>
        <artifactId>cargo-maven2-plugin</artifactId>
        <version>1.1.2</version>
        <executions>
            <execution>
                <phase>deploy</phase>
                <goals>
                    <goal>deployer-redeploy</goal>
                </goals>
            </execution>
        </executions>
        <configuration>
            <container>
                <containerId>${mule.deploy.containerId}</containerId>
                <type>remote</type>
            </container>
            <configuration>
                <type>runtime</type>
                <properties>
                    <cargo.server.settings>${mule.deploy.serverId}</cargo.server.settings>
                </properties>
            </configuration>
        </configuration>
    </plugin>
</plugins>

The Cargo plugin is attached to the deploy lifecycle phase of Maven. Which means that the deployer-redeploy goal will be executed whenever you type: mvn deploy. The plugin uses the defined configuration at runtime. I used the depoyer-redeploy goal, because this goal will deploy your app if it is not yet deployed, and undeploy first when it is already deployed. More info on the Cargo plugin here.

The properties will be resolved from your settings.xml in which we have defined several profiles: one for each target environment (i.e. develop, test, qa).

Here’s an example for a development environment (you can add the profiles for the other target environment yourself):

Add the following (inside the <profiles> tag) to your ~/.m2/settings.xml:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
<profile>
    <id>develop</id>
    <properties>
        <mule.deploy.containerId>tomcat7x</mule.deploy.containerId>                
        <mule.deploy.serverId>develop</mule.deploy.serverId>
    </properties>
    <activation>
        <activeByDefault>false</activeByDefault>
            <property>
            <name>env</name>
            <value>dev</value>
            </property>
    </activation>
</profile>

Also, add a definition with id=develop (inside the <servers> tag):

1
2
3
4
5
6
7
8
<server>
    <id>develop</id>
    <configuration>
        <cargo.remote.uri>http://localhost:8080/manager/text</cargo.remote.uri>
        <cargo.remote.username>deploy</cargo.remote.username>
        <cargo.remote.password>deploy</cargo.remote.password>
    </configuration>
</server>

The trick here is to add the Cargo configuration to the server definition. The defined properties are used by Maven to automagically deploy your webapp. In this demo I used localhost, but it could also be a remote host.

Note that I used a username and password for the deployment process. Add these in your $CATALINA_HOME/conf/tomcat-users.xml:

1
<user username="deploy" password="deploy" roles="manager-script"/>

Note: user _must_ have the manager-script role!

Now, all that’s left is deploying your application by executing mvn clean deploy -Denv=dev. The property env=dev will activate the correct profile in your settings.xml and resolve the earlier mentioned properties. BUT, the deploy phase requires a distributionManagement tag in your pom.xml. Mine looks like this (PS: I use JFrog Artifactory):

1
2
3
4
5
6
7
8
9
10
<distributionManagement>
    <repository>
        <id>artifactory</id>
        <url>http://dev.foobar.local:8080/artifactory/libs-release-local/</url>
    </repository>
    <snapshotRepository>
        <id>artifactory</id>
        <url>http://dev.foobar.local:8080/artifactory/libs-snapshot-local</url>
    </snapshotRepository>
</distributionManagement>

After you’ve added this to your pom, you’re ready to deploy your application.

Result:

...
[INFO]
[INFO] --- cargo-maven2-plugin:1.1.2:deployer-redeploy (default) @ simplewebapp ---
[INFO] [mcat7xRemoteDeployer] [/Users/pprins/projects/sandbox/simplewebapp/target/simplewebapp.war] is not deployed. Doing a fresh deployment.
[INFO] [mcat7xRemoteDeployer] Deploying [/Users/pprins/projects/sandbox/simplewebapp/target/simplewebapp.war]
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 5.569s
[INFO] Finished at: Fri Oct 07 13:20:24 CEST 2011
[INFO] Final Memory: 7M/554M
[INFO] ------------------------------------------------------------------------

Goto: http://localhost:8080/simplewebapp et voila: your web app!

A redeploy would look something like this:

...
[INFO] --- cargo-maven2-plugin:1.1.2:deployer-redeploy (default) @ simplewebapp ---
[INFO] [mcat7xRemoteDeployer] Redeploying [/Users/pprins/projects/sandbox/simplewebapp/target/simplewebapp.war]
[INFO] [mcat7xRemoteDeployer] Undeploying [/Users/pprins/projects/sandbox/simplewebapp/target/simplewebapp.war]
[INFO] [mcat7xRemoteDeployer] Deploying [/Users/pprins/projects/sandbox/simplewebapp/target/simplewebapp.war]
categories: Maven

About Pascal Prins

Started in 1996. Eye for detail and environment. Broad experience, mainly covering integration related technologies, tools and solutions. Involved in many projects as technical lead, architect or business consultant. One wife, two beautiful daughters, one magnificent son ... and one cat.

Comments are closed.