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

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:
  2. Run the WildFly container, with MySQL JDBC resource pre-configured, as:
  3. Find the IP address of the WildFly container:
    If you are on a Mac, then use boot2docker ip to find the IP address.
  4. Access the application as:
    to see the output as:
    The application is a trivial Java EE 7 application that publishes a REST endpoint. Access it as:
    to see:

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:

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:

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:

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

Enjoy!

Be Sociable, Share!
  • Tweet

16 thoughts on “WildFly/JavaEE7 and MySQL linked on two Docker containers (Tech Tip #66)

  1. Pingback: A Simple Java EE Docker Example | Rafael Pestano
  2. Pingback: Java EE 7 and WildFly on Kubernetes using Vagrant - Java吧
  3. Pingback: 9 Docker recipes for Java EE Applications | Indie Game Developer!
  4. Pingback: Docker MySQL Persistence (Tech Tip #83) | Social Marketing by I88.CA
  5. Hello Arun,

    I notice that if I restart the container, it will try to create the datasource again in Wildfly.
    Is there a way to avoid this after the first start?

    Thanks

  6. Guilherme,

    It will give an error but the data source will not be created again though, right?

    Anyway following up and will get back to you.

  7. Yes, it won’t be created again.

    But I customized to use in other application, that uses JMS, Java mail and Modeshap, it is a lot of commands that will polute the log, so I would like to avoid this.

    I’m thinking about to use a environment variable to flag if it was run or not, but I don’t know if it is a good idea.

    Thanks

  8. The Wildfly in a non-Docker won’t execute the commands.

    I’m new to Docker, so sorry if it’s not a good question. I would like to just execute the wildfly commands once and when it restarts, it can start faster without trying to create everything again.

    By the way I like your container.
    Thanks

  9. You can consider creating a custom image with your DataSources etc baked in. This will involve writing a Dockerfile and invoking jboss-cli scripts that will make those checks, and create if necessary.

  10. Pingback: How do you deploy to JBoss EAP sitting within a running docker container using the jboss-as-maven-plugin? - CSS PHP
  11. Hello,

    I am starting mysql first and seems its OK, but when starting wildfly there is exception.
    WFLYCTL0186: Services which failed to start: service jboss.persistenceunit.”employees.war#MyPU”

  12. Error i am getting :

    ERROR [org.jboss.msc.service.fail] (ServerService Thread Pool — 58) MSC000001: Failed to start service jboss.persistenceunit.”employees.war#MyPU”: org.jboss.msc.service.StartException in service jboss.persistenceunit.”employees.war#MyPU”: org.hibernate.HibernateException: Access to DialectResolutionInfo cannot be null when ‘hibernate.dialect’ not set
    at org.jboss.as.jpa.service.PersistenceUnitServiceImpl$1$1.run(PersistenceUnitServiceImpl.java:172)

Leave a Reply

Your email address will not be published. Required fields are marked *