We are trying to automate the installation of our software within Docker and it’s been my job to try to figure out how. This has been a learning process for me, since I had only looked at Docker before and had not delved into it too deeply.
For those who are as clueless as I was, Docker takes virtualization further. Rather than virtualizing a whole server, Docker works at the application level. Using this technology, a developer can create a application system that can be installed in another environment running Docker with much more ease. No more major configuration issues: it just works.
Docker is still quite new and Docker Compose is even newer, which means little is found on the Web outside the official website. So I’m hoping my results will help someone else.
I was trying to set up a Wildfly in one Docker instance, with our application deployed to it. I was trying to run a second instance with with MySQL and connect them together. Docker Compose made it possible to do this, and expose the database port to the Wildfly instance, without exposing it to the outside world. This, hopefully, would make the system more secure. It is still possible to run mysql commands, such as mysqldump, allowing backups to the filesystem outside of the instance. A bash shell is also possible so that mysql can be viewed through the command line. Mind you, MySQL’s port can be exposed, if that’s necessary for your needs. It wasn’t for mine.
I followed JBoss’ tutorial for Wildfly in the Docker environment. The first part of the tutorial shows how to Dockerize Wildfly, not exposing the management interface and using a mapped drive for deployed files.
RUN /opt/jboss/wildfly/bin/add-user.sh admin [admin pw] --silent
# the following line was needed for my sample application
COPY jaxb-impl.jar /opt/jboss/wildfly/standalone/lib/ext
CMD ["/opt/jboss/wildfly/bin/standalone.sh","-b","0.0.0.0", -bmanagement","0.0.0.0"]
Notice that ports aren’t exposed within the Dockerfile for this instance. I handled that within the Docker Compose file.
MySQL’s Docker page was useful in getting my instance set up. The one big issue I had was trying to figure out how to set up my tables after creating the database within the context of the Dockerfile. Remember: my purpose is to try to automate this as much as possible. Without the ability to automate schema setup, the effort would have been made much more difficult.
I finally found in the documentation the ONBUILD option. This option allows a command to be inserted into the Dockerfile that is run after installation.
Here’s my MySql Dockerfile:
ENV MYSQL_ROOT_PASSWORD [root pw]
ENV MYSQL_DATABASE [my database - created with installation]
ENV MYSQL_USER [my database user]
ENV MYSQL_PASSWORD [my database user password]
# copy over the script that creates my tables and populates them
ADD SpringTest.sql tmp/
# one line that took me hours to figure out
ONBUILD run mysql -uroot -p"$MYSQL_ROOT_PASSWORD" $MYSQL_DATABASE < tmp/SprintTest.sql
Docker Compose allows the starting of several appliances at once, and the ability to easily link them together as if they were on a single machine. It’s not considered ‘ready for prime time’. But my simple tests showed nothing that would prevent me from utilizing this capability.
Here’s the content of my docker-compose.yml file:
# this allowed the building of the custom configuration I created above
# which resides in a 'MySql' subdirectory
# exposes the port to the shared appliance, but not to the outside world
I wrote a sample Spring application to test in this environment. The thing that needs to be noted is the database connection:
<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="com.mysql.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://db:3306/SpringTest"/>
<property name="username" value="[same as MYSQL_USER]"/>
<property name="password" value="[same as MYSQL_PASSWORD]"/>
Hopefully, this will save someone else some headaches. Leave a comment if you need more help to get your instances working.