Containerize a Java EE web application with MySQL, phpmyadmin, and Tomcat services
In this article, we will create a Docker Compose file with three services: MySQL, phpmyadmin, and Tomcat. Compose allows us to configure these services with a single YAML file.
First, create a docker-compose.yml file at the root of your project.
Initialize the Compose file as the following gist suggests.
The version key indicates the Compose file version.- db: The MySQL service
- pma: The phpmyadmin service
- web: The Tomcat service
Now I will tell you what the configuration of each of our service looks like, and what it means.
MySQL
We will use a MySQL database as the datastore for our application, hence the MySQL service. Initialize the db service as following:
Here, we specify the official MySQL version 5.7 docker image for our service. Then, we name the container mysql. Also, we instruct Compose to always restart the service.
Next, we specify the volumes to be mounted and the location to mount them to.
Note that the mysql-dump location acts as a dump for the database when the service has stopped.
Also, the mysql-init location contains the initialization script for our database; including the script to create the required tables and dummy data to use. The mysql container looks in its docker-entrypoint-initdb.d location for any such initialization script(s) to execute once the container starts running.
You can place an initialization script inside mysql-init, one such as the following:
Note that I exported an existing MySQL table using phpmyadmin GUI to generate the above script.
Now, we pass some environment variables to our container, these are required for us to access the MySQL service from our other services.
Then, we expose the MySQL service to our host machine's 3306 port.
phpmyadmin
We need the phpmyadmin service to access our database with a GUI. This prevents us the hassle of using the docker exec command to access the db service using the CLI. To configure the service, consult the following snippet:
Here we specify the depends_on key, this indicates that the pma service is dependent on the db service.
Similar to the previous service, we specify the image to use, container name, restart policy, environment variables, and the host machine ports to expose.
After the service is up and running, we can access the phpmyadmin GUI via localhost:8081.
Tomcat
Finally, we configure the web service.
Here, again, we specify a dependency between the web and the db service via the depends_on key. Then, after specifying the image to use, what to name the container, you can see that I mount a .war file onto a specific location inside the container.
I've mounted a ContactBook.war file, but you can replace that by the name of your project.
Tomcat looks inside the /usr/local/tomcat/webapps/ location to deploy a web application. Here, we mount the Web Application Archive (war) file generated by the IDE.
Next, we specify the restart policy, port mapping, and the environment variables. These environment variables can be accessed from our Java application using System.getenv().
With our port mapping, we will be accessing our Java application from localhost:8080.
Finally, the docker-compose.yml file should look like:
JDBC
After we have configured our service, we need to configure our Java application running inside the Tomcat container to use the db service. For this, we can create a DbUtil class to create and manage connections.
You can see how I've used the environment variables passed into the tomcat container.
Running the application
First, generate a .war file from your IDE of choice inside build/ directory at the root of your project. Then run the application using docker-compose up.
As I have mentioned above, we can now access our Java application via localhost:8080/ContactBook.war. Just replace ContactBook by the name of your project.
Here you go, you've just configured a multi-container Docker application and successfully run it!