DevOps

WildFly/JavaEE7 and MySQL linked on two Docker containers (Tech Tip #65)

Tech Tip #61 showed how to run Java EE 7 hands-on lab on WildFly Docker container. A couple of assumptions were made in that case:
 
 
 
 
 
 
 
 
 

 
 

  • WildFly bundles H2 in-memory database. The Java EE 7 application uses the default database resource, which in case of WildFly, gets resolved to a JDBC connection to that in-memory database. This is a good way to start building your application but pretty soon you want to start using a real database, like MySQL.
  • Typically, Application Server and Database may not be residing on the same host. This reduces the risk by avoiding a single point of failure. And so WildFly and MySQL would be on to separate host.

There is plethora of material available to show how to configure WildFly and MySQL on separate hosts. What are the design patterns, and anti-patterns, if you were to do that using Docker?

Lets take a look!

In simplified steps:

  1. Run the MySQL container as:
    docker run --name mysqldb -e MYSQL_USER=mysql -e MYSQL_PASSWORD=mysql -e MYSQL_DATABASE=sample -e MYSQL_ROOT_PASSWORD=supersecret -d mysql 
  2. Run the WildFly container, with MySQL JDBC resource pre-configured, as:
    docker run --name mywildfly --link mysqldb:db -p 8080:8080 -d arungupta/wildfly-mysql-javaee7 
  3. Find the IP address of the WildFly container:
    sudo docker inspect -f '{{ .NetworkSettings.IPAddress }}' mywildfly 

    If you are on a Mac, then use boot2docker ip to find the IP address.

  4. Access the application as:
    curl http://<IP_ADDRESS>:8080/employees/index.html 

    to see the output as:

The application is a trivial Java EE 7 application that publishes a REST endpoint. Access it as:

curl http://localhost:8080/employees/resources/employees/

to see:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?><collection><employee><id>1</id><name>Penny</name></employee><employee><id>2</id><name>Sheldon</name></employee><employee><id>3</id><name>Amy</name></employee><employee><id>4</id><name>Leonard</name></employee><employee><id>5</id><name>Bernadette</name></employee><employee><id>6</id><name>Raj</name></employee><employee><id>7</id><name>Howard</name></employee><employee><id>8</id><name>Priya</name></employee></collection>

If you are interested in nitty gritty, read further details.

Linking Containers

The first concept we need to understand is how Docker allows linking containers. Creating a link between two containers creates a conduit between a source container and a target container and securely transfer information about source container to target container. In our case, target container (WildFly) can see information about source container (MySQL). The important part to understand here is that none of this information needs to be publicly exposed by the source container, and is only made available to the target container.

The magic switch to enable link is, intuitively, --link. So for example, if MySQL and WildFly containers are run as shown above, then --link mysqldb:db links the MySQL container named mysqldb with an alias db to the WildFly target container. This defines some environment variables, following the defined protocol, in the target container which can then be used to access information about the source container. For example, IP address, exposed ports, username, passwords, etc. The complete list of environment variables can be seen as:

[arun@localhost wildfly-mysql-javaee7]$ sudo docker run --name mywildfly --link mysqldb:db -p 8080:8080 -it arungupta/wildfly-mysql-javaee7 env
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
HOSTNAME=4e0458981a82
TERM=xterm
DB_PORT=tcp://172.17.0.24:3306
DB_PORT_3306_TCP=tcp://172.17.0.24:3306
DB_PORT_3306_TCP_ADDR=172.17.0.24
DB_PORT_3306_TCP_PORT=3306
DB_PORT_3306_TCP_PROTO=tcp
DB_NAME=/mywildfly3/db
DB_ENV_MYSQL_USER=mysql
DB_ENV_MYSQL_PASSWORD=mysql
DB_ENV_MYSQL_DATABASE=sample
DB_ENV_MYSQL_ROOT_PASSWORD=supersecret
DB_ENV_MYSQL_MAJOR=5.6
DB_ENV_MYSQL_VERSION=5.6.22
JAVA_HOME=/usr/lib/jvm/java
WILDFLY_VERSION=8.2.0.Final
JBOSS_HOME=/opt/jboss/wildfly
HOME=/opt/jboss

So you can see there are DB_* environment variables providing plenty of information about source container.

Linking only works if all the containers are running on the same host. A better solution will be shown in the subsequent blog, stay tuned.

Override default Docker command

Dockerfile for this image inherits from jboss/wildfly:latest and starts the WildFly container. Docker containers can only run one command but we need to install JDBC driver, create JDBC resource using the correct IP address and port, and deploy the WAR file. So we will override the command by inheriting from jboss/wildfly:latest and use a custom command. This command will do everything that we want to do, and then start WildFly as well.

The custom command does the following:

  • Add MySQL module
  • Add MySQL JDBC driver
  • Add the JDBC data source using IP address and port of the linked MySQL container
  • Deploy the WAR file
  • Start WildFly container

Note, WildFly is starting with -b 0.0.0.0 that allows it to be bound to any IP address. Also, the command needs to run in foreground so that the container stays active.

Customizing security

Ideally, you’ll poke holes in the firewall to enable connection to specific host/ports. But these instructions were tried on Fedora 20 running in Virtual Box. So for convenience, the complete firewall was disabled as:

[arun@localhost wildfly-mysql-javaee7]$ sudo docker run --name mywildfly --link mysqldb:db -p 8080:8080 -it arungupta/wildfly-mysql-javaee7 env
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
HOSTNAME=4e0458981a82
TERM=xterm
DB_PORT=tcp://172.17.0.24:3306
DB_PORT_3306_TCP=tcp://172.17.0.24:3306
DB_PORT_3306_TCP_ADDR=172.17.0.24
DB_PORT_3306_TCP_PORT=3306
DB_PORT_3306_TCP_PROTO=tcp
DB_NAME=/mywildfly3/db
DB_ENV_MYSQL_USER=mysql
DB_ENV_MYSQL_PASSWORD=mysql
DB_ENV_MYSQL_DATABASE=sample
DB_ENV_MYSQL_ROOT_PASSWORD=supersecret
DB_ENV_MYSQL_MAJOR=5.6
DB_ENV_MYSQL_VERSION=5.6.22
JAVA_HOME=/usr/lib/jvm/java
WILDFLY_VERSION=8.2.0.Final
JBOSS_HOME=/opt/jboss/wildfly
HOME=/opt/jboss

In addition, a Host-only adapter was added using Virtual Box settings and looks like:

techtip65-host-only-adapter

That’s it, that should get you going to to use WildFly and MySQL on two separate containers.

Also verified the steps on boot2docker, and it worked seamlessly there too:

docker-images> docker run --name mysqldb -e MYSQL_USER=mysql -e MYSQL_PASSWORD=mysql -e MYSQL_DATABASE=sample -e MYSQL_ROOT_PASSWORD=supersecret -d mysql
docker-images> 
docker-images> docker run --name mywildfly --link mysqldb:db -p 8080:8080 -d arungupta/wildfly-mysql-javaee7
Unable to find image 'arungupta/wildfly-mysql-javaee7' locally
Pulling repository arungupta/wildfly-mysql-javaee7
791773b0e1de: Download complete 
511136ea3c5a: Download complete 
782cf93a8f16: Download complete 
7d3f07f8de5f: Download complete 
1ef0a50fe8b1: Download complete 
20a1abe1d9bf: Download complete 
cd5bb934bb67: Download complete 
379edb00ab07: Download complete 
4d37cbbfc67d: Download complete 
2ea8562cac7c: Download complete 
7759146eab1a: Download complete 
b17a20d6f5f8: Download complete 
e02bdb6c4ed5: Download complete 
72d585299bb5: Download complete 
90832e1f0bb9: Download complete 
2c3484b42034: Download complete 
38fad13dea25: Download complete 
656878d9a6c6: Download complete 
6510de96c354: Download complete 
0cc86be8ac93: Download complete 
cc4e21e8b0e7: Download complete 
Status: Downloaded newer image for arungupta/wildfly-mysql-javaee7:latest
8522df362e57f5b7a5324dba692559b971c7cfda4a687212c44b1118008a4c63
docker-images> curl http://192.168.59.103:8080/employees/index.html
        
        
  • GET all employees.
  • GET 1 employee.
    

docker-images> curl http://192.168.59.103:8080/employees/resources/employees/
1Penny2Sheldon3Amy4Leonard5Bernadette6Raj7Howard8Priya

Source code for the image is at github.com/arun-gupta/docker-images/tree/master/wildfly-mysql-javaee7.

Enjoy!

Arun Gupta

Arun is a technology enthusiast, avid runner, author of a best-selling book, globe trotter, a community guy, Java Champion, JavaOne Rockstar, JUG Leader, Minecraft Modder, Devoxx4Kids-er, and a Red Hatter.
Subscribe
Notify of
guest

This site uses Akismet to reduce spam. Learn how your comment data is processed.

0 Comments
Inline Feedbacks
View all comments
Back to top button