Duke's Bank J2EE Jenkins/Rundeck example
This example combines Jenkins and Rundeck to implement automated build and release.
The basic notion is one of continuous build and deployment: each commit to the source repository (Subversion in this case) automatically triggers Jenkins to rebuild one or other of the application's deployable artifacts (the Duke's Bank ear file and a configuration package), after which Jenkins calls a Rundeck job to deploy to a JBoss instance running on one or more target nodes.
Contents |
Setup
This section describes how to setup the example from scratch.
System
While the example no doubt works on any recent release of CentOS, it has been tested on releases 5.4, 5.5, and 5.7 (64-bit).
System requirements are reasonably modest with testing being completed on a single AWS EC2 instances (10GB EBS file system, and 8GB RAM). Note that it's quite straightforward to spread all the services out across individual system instances too.
The example includes:
- Apache web server acting as a Subversion server and web-based package repository
- Jenkins server to manage builds
- Rundeck server to manage deployment
- JBoss as the Duke's Bank application server
- MySQL for the Duke's Bank database
No matter how many system instances you end up with, it pays to get DNS sorted out upfront since host names get configured all over the place! This documentation was tested using the following set of names (all resolving to "dukesbank.dtolabs.com") :
- sources.dukesbank.dtolabs.com - source code control system (Subversion)
- build.dukesbank.dtolabs.com - build system (Jenkins)
- deploy.dukesbank.dtolabs.com - deployment system (Rundeck)
- app.dukesbank.dtolabs.com - application server system (JBoss)
- db.dukesbank.dtolabs.com - database server system (MySQL)
So, that being said, step one after the VM is running is to set up your hosts file and hostname. Log in as root and run the following:
hostname dukesbank.dtolabs.com cat >> /etc/hosts <<EOH # Do not remove the following line, or various programs # that require network functionality will fail. 127.0.0.1 dukesbank.dtolabs.com dukesbank sources.dukesbank.dtolabs.com build.dukesbank.dtolabs.com deploy.dukesbank.dtolabs.com app.dukesbank.dtolabs.com db.dukesbank.dtolabs.com localhost.localdomain localhost ::1 localhost6.localdomain6 localhost6 EOH
Note that this kind of role-base system naming offers a great degree of flexibility since the aliases that represent the role can be easily be switched from one canonical domain name to another. Better still, they provide a human-readable mnemonic!
Beyond a basic system image, the example requires the following tools to be installed:
- Java (see Java on CentOS)
- Subversion client (see Subversion on CentOS )
- Git (see Git on CentOS)
Tool-chain
Subversion
- Follow Apache mod-dav-svn on CentOS to setup the Subversion server with an empty repository called "dukes bank". e.g.: http://sources.dukesbank.dtolabs.com/repos/dukesbank
Jenkins
Install JBoss first
- Since Duke's Bank is built using JBoss, download the required version and install it on the build system (e.g. build.dukesbank.dtolabs.com). We're also saving the zipfile for later use:
cd /opt wget -q http://sourceforge.net/projects/jboss/files/JBoss/JBoss-4.0.3SP1/jboss-4.0.3SP1.zip/download unzip -q jboss-4.0.3SP1.zip cp jboss-4.0.3SP1.zip /root/ ls jboss-4.0.3SP1
And the output of your ls should be:
bin client docs jar-versions.xml lib readme.html readme_j2ee.html server
- Follow Jenkins on CentOS to get a basic Jenkin's instance running. e.g.: http://build.dukesbank.dtolabs.com:8080 (Log in as admin/admin)
- Navigate to the "Configure System" page (e.g.: http://build.dukesbank.dtolabs.com:8080/manage) and setup the latest version of Ant to be downloaded from Apache:
- Navigate to the "Plugin Manager" page (e.g.: http://build.dukesbank.dtolabs.com:8080/pluginManager/) and install Rundeck plugin (you'll be prompted to restart Jenkins).
- Configure the Rundeck plug-in from the "Configure System" page as follows:
Rundeck
- Follow Rundeck on CentOS to get Rundeck installed and running. e.g.: http://deploy.dukesbank.dtolabs.com:4440
Platform
Duke's Bank is a two-tier application requiring both an application and database server.
JBoss
JBoss needs to be pre-setup since this example does not demonstrate automating application server installation itself.
- Follow JBoss on CentOS to get a copy of JBoss 4.0.3SP1 installed on the system designated as the application server. Instead of downloading the zipfile again, just copy it from /root.
- Download the latest version of the MySQL Connector/J JDBC driver.
- su to the jboss user and:
wget -q http://www.mysql.com/get/Downloads/Connector-J/mysql-connector-java-5.1.17.zip/from/http://mysql.mirrors.pair.com/ unzip mysql-connector-java-5.1.17.zip cp mysql-connector-java-5.1.17/mysql-connector-java-5.1.17-bin.jar jboss-4.0.3SP1/server/default/lib
- Exit out of the jboss user and back to the root id:
MySQL
- Follow MySQL on CentOS to get the database server running on the designated system (e.g. db.dukesbank.dtolabs.com)
- As the root user:
- Create the Duke's Bank database:
# mysql Welcome to the MySQL monitor. Commands end with ; or \g. Your MySQL connection id is 3 Server version: 5.0.77 Source distribution Type 'help;' or '\h' for help. Type '\c' to clear the buffer. mysql> create database dukesbank; Query OK, 1 row affected (0.01 sec)
- Create the Duke's Bank user giving it full access to the database:
# mysql Welcome to the MySQL monitor. Commands end with ; or \g. Your MySQL connection id is 5 Server version: 5.0.77 Source distribution Type 'help;' or '\h' for help. Type '\c' to clear the buffer. mysql> CREATE USER 'dukesbank'@'locahost' IDENTIFIED BY 'dukesbank'; Query OK, 0 rows affected (0.00 sec) mysql> CREATE USER 'dukesbank'@'%' IDENTIFIED BY 'dukesbank'; Query OK, 0 rows affected (0.00 sec) mysql> GRANT ALL PRIVILEGES ON dukesbank.* TO 'dukesbank'@'localhost'; Query OK, 0 rows affected (0.00 sec) mysql> GRANT ALL PRIVILEGES ON dukesbank.* TO 'dukesbank'@'%'; Query OK, 0 rows affected (0.00 sec) mysql> FLUSH PRIVILEGES; Query OK, 0 rows affected (0.00 sec) mysql> Bye
- Test the connection (remotely from the application server(s) if you're planning to use more than one system):
# mysql -D dukesbank -P 3306 -h db.dukesbank.dtolabs.com -u dukesbank --password=dukesbank Welcome to the MySQL monitor. Commands end with ; or \g. Your MySQL connection id is 4 Server version: 5.0.77 Source distribution Type 'help;' or '\h' for help. Type '\c' to clear the buffer. mysql> create table foo(bar int); Query OK, 0 rows affected (0.09 sec) mysql> select * from foo; Empty set (0.08 sec) mysql> drop table foo; Query OK, 0 rows affected (0.09 sec) mysql> Bye
Application
Setup a "developer" account
- As root:
useradd anthony usermod -G rundeck anthony su - anthony id
Output:
uid=502(anthony) gid=502(anthony) groups=500(rundeck),502(anthony)
Get example source code
The Duke's Bank application source code and data as well as other files to support this example are kept in the dtolabs/dukesbank repository on GitHub.
- Clone a copy of the Duke's Bank repository on GitHub.
- As your development user:
cd ~ mkdir src cd src git clone git://github.com/dtolabs/dukesbank.git
Output:
Initialized empty Git repository in /home/anthony/src/dukesbank/.git/ remote: Counting objects: 1865, done. remote: Compressing objects: 100% (956/956), done. remote: Total 1865 (delta 816), reused 1865 (delta 816) Receiving objects: 100% (1865/1865), 29.66 MiB | 1959 KiB/s, done. Resolving deltas: 100% (816/816), done.
- Review the layout of the source:
ls dukesbank
Output:
README data examples src
Setup the database
Since this example is not concerned with formally managing the release of the application's database schema and data, it's OK just to load the sample data that makes Duke's Bank work directly to MySQL!
- Load the sample data (again, as the development user):
mysql -D dukesbank -h db.dukesbank.dtolabs.com -P 3306 -u dukesbank --password=dukesbank < dukesbank/data/mysql/dukesbank.sql
- Check that the tables are loaded:
$ mysql -D dukesbank -h db.dukesbank.dtolabs.com -P 3306 -u dukesbank --password=dukesbank Reading table information for completion of table and column names You can turn off this feature to get a quicker startup with -A Welcome to the MySQL monitor. Commands end with ; or \g. Your MySQL connection id is 7 Server version: 5.0.77 Source distribution Type 'help;' or '\h' for help. Type '\c' to clear the buffer. mysql> show tables; +-----------------------+ | Tables_in_dukesbank | +-----------------------+ | ACCOUNT | | CUSTOMER | | CUSTOMER_ACCOUNT_XREF | | NEXT_ID | | TX | +-----------------------+ 5 rows in set (0.00 sec) mysql> Bye
Populate the Subversion repository
The example source is included in the GitHub repository, so it's trivial to import it into the Subversion repository.
- Import the Duke's Bank application source to the Subversion server:
export EDITOR=vi cd /home/anthony/src/dukesbank svn import src http://sources.dukesbank.dtolabs.com/repos/dukesbank/trunk/src
Output:
Adding (bin) src/j2eetutorial14.zip . . . Adding src/j2eetutorial14/examples/saaj/headers/src Adding src/j2eetutorial14/examples/saaj/headers/src/HeaderExample.java Adding src/j2eetutorial14/examples/saaj/headers/build.xml Committed revision 5.
- Import the example's JBoss configuration files:
$ svn import examples/example1/jboss http://sources.dukesbank.dtolabs.com/repos/dukesbank/trunk/examples/example1/jboss Adding examples/example1/jboss/server Adding examples/example1/jboss/server/default Adding examples/example1/jboss/server/default/conf Adding examples/example1/jboss/server/default/conf/bindings.xml Adding examples/example1/jboss/server/default/conf/jboss-service.xml Adding examples/example1/jboss/server/default/deploy Adding examples/example1/jboss/server/default/deploy/mysql-ds.xml Committed revision 8.
Setup Rundeck resources
Since this example does not formally manage the Rundeck resources, its OK just to add the application server node directly to the project.
- Add the application server to the Rundeck node list.
- As your development user:
vi /var/rundeck/projects/DukesBank/etc/resources.xml
It should look like this:
<?xml version="1.0" encoding="UTF-8"?> <project> <node name="localhost" description="Rundeck server node" tags="" hostname="localhost" osArch="amd64" osFamily="unix" osName="Linux" osVersion="2.6.21.7-2.fc8xen" username="rundeck"/> <node name="jboss@app.dukesbank.dtolabs.com" description="Duke's Bank JBoss account" tags="DukesBank,Example1,JBoss" hostname="app.dukesbank.dtolabs.com" osArch="amd64" osFamily="unix" osName="Linux" osVersion="2.6.21.7-2.fc8xen" username="jboss"/> </project>
- Setup ssh key-based authentication between the Rundeck server user (e.g. rundeck@deploy.dukesbank.dtolabs.com) and the JBoss application server user (e.g. jboss@app.dukesbank.dtolabs.com).
- As root:
fgrep framework.ssh.keypath /etc/rundeck/framework.properties
Output:
framework.ssh.keypath = /home/rundeck/.ssh/rundeck.id_rsa
Now, we can use that information:
mkdir ~jboss/.ssh cp /home/rundeck/.ssh/rundeck.id_rsa.pub ~jboss/.ssh/authorized_keys chown -R jboss:jboss ~jboss/.ssh chmod 700 ~jboss/.ssh chmod 600 ~jboss/.ssh/authorized_keys
- Test the configuration by running a command to the JBoss server from Rundeck (e.g. http://deploy.dukesbank.dtolabs.com:4440/run):
- Note: Need clear instructions to set up the jboss command environment in Rundeck here!
Load Rundeck jobs
The example source includes a set of Rundeck jobs design to manage the JBoss server running the application server system(s).
- Load the jobs.
- As the development user:
cd ~/src rd-jobs load --file dukesbank/examples/example1/rundeck/jobs.xml
Output:
# Total Jobs Uploaded: 5 jobs # Succeeded creating/updating 5 Jobs: succeeded: - Example1/JBoss/Configure - Example1/JBoss/Deploy - Example1/JBoss/Install - Example1/JBoss/Start - Example1/JBoss/Stop
- Review the jobs using the Rundeck console (e.g. http://deploy.dukesbank.dtolabs.com:4440/jobs):
Load Jenkins jobs
- Load the configuration build job.
- As your development user:
cd ~/src/dukesbank curl -S -H "Content-Type: text/xml" -s --data-binary "@examples/example1/jenkins/Example1Conf/config.xml" "http://build.dukesbank.dtolabs.com:8080/createItem?name=Example1Conf"
- Load the code build job:
cd ~/src/dukesbank curl -S -f -H "Content-Type: text/xml" -s --data-binary "@examples/example1/jenkins/Example1Code/config.xml" "http://build.dukesbank.dtolabs.com:8080/createItem?name=Example1Code"
Where do we go from here?



