Search code examples
dockerubuntu-16.04tomcat8

How to run Tomcat 8 and MySQL in single Docker container


I have a Tomcat 8 / MySQL application I want to run in a docker container. I run Ubuntu 16.04 today in test and production and wanted use the Ubuntu 16.04 "latest" as the base FROM to my docker file and add Tomcat 8 and MySQL from there.

I know I can get a Tomcat 8 docker file as my base from https://hub.docker.com/_/tomcat/ but I did not see an Ubuntu base OS for those and I wanted to stay consistent with Ubuntu. Also, it seemed odd to add MySQL to a Tomcat container.


Solution

  • I worked through this issue and am posting my findings in case it helps others with similar issues.

    Short answer: Running multiple services (tomcat / mysql) in a single container is not recommended. Yes, there is supervisor.d, etc. But this is discouraged. There is also baseimage-docker if you are committed to multiple services in one container.

    The remainder of this answer shows how I got it working it if you really are determined...

    The Tomcat 8 distro version on Ubuntu 16.04 is unfortunately only configured to run as a service (described in detail below). Issues with running a service in a docker container are documented well in many posts across stack exchange (it is discouraged). I was able to get tomcat 8 working as a service by adding a "tail -f /var/log/tomcat8/catalina.out" to the end of the "service tomcat8 start" command and starting the container with the "--cap-add SYS_PTRACE" option.

    CMD service tomcat8 start && tail -f /var/log/tomcat8/catalina.out
    

    The recommended way to start tomcat8 is to use the commands in /usr/share/tomcat8/bin. However, the distro version's soft links are incorrect and the server fails to start.

    Using the commands ./catalina.sh run or ./startup.sh both produce an error such as this:

    SEVERE: Cannot find specified temporary folder at /usr/share/tomcat8/temp   
    WARNING: Unable to load server configuration from [/usr/share/tomcat8/conf/server.xml]
    SEVERE: Cannot start server. Server instance is not configured.
    

    The distro splits tomcat8 across /usr/share/tomcat8 and /var/lib/tomcat8 which separates the bin files (catalina.sh and startup.sh) from the config and logs soft links in /var/lib/tomcat8. This makes these commands fail.

    Files in /usr/share/tomcat8:

    root@85d5fe47b66a:/usr/share/tomcat8# ls -la
    total 32
    drwxr-xr-x   4 root root 4096 Mar  9 22:18 .
    drwxr-xr-x 117 root root 4096 Mar  9 23:29 ..
    drwxr-xr-x   2 root root 4096 Mar  9 22:18 bin
    -rw-r--r--   1 root root   39 Mar 31  2017 defaults.md5sum
    -rw-r--r--   1 root root 1929 Apr 10  2017 defaults.template
    drwxr-xr-x   2 root root 4096 Mar  9 22:18 lib
    -rw-r--r--   1 root root   53 Mar 31  2017 logrotate.md5sum
    -rw-r--r--   1 root root  118 Apr 10  2017 logrotate.template
    

    Files in /var/lib/tomcat8:

    root@85d5fe47b66a:/var/lib/tomcat8# ls -la
    total 16
    drwxr-xr-x  4 root    root    4096 Mar  9 22:18 .
    drwxr-xr-x 41 root    root    4096 Mar  9 23:29 ..
    lrwxrwxrwx  1 root    root      12 Sep 28 14:43 conf -> /etc/tomcat8
    drwxr-xr-x  2 tomcat8 tomcat8 4096 Sep 28 14:42 lib
    lrwxrwxrwx  1 root    root      17 Sep 28 14:43 logs -> ../../log/tomcat8
    drwxrwxr-x  3 tomcat8 tomcat8 4096 Mar  9 22:18 webapps
    lrwxrwxrwx  1 root    root      19 Sep 28 14:43 work -> ../../cache/tomcat8
    

    Running ./version.sh reveals that both CATALINA_BASE and CATALINA_HOME are set to /usr/share/tomcat8

    Using CATALINA_BASE:   /usr/share/tomcat8
    Using CATALINA_HOME:   /usr/share/tomcat8
    Using CATALINA_TMPDIR: /usr/share/tomcat8/temp
    Using JRE_HOME:        /usr
    Using CLASSPATH:       /usr/share/tomcat8/bin/bootstrap.jar:/usr/share/tomcat8/bin/tomcat-juli.jar
    Server version: Apache Tomcat/8.0.32 (Ubuntu)
    Server built:   Sep 27 2017 21:23:18 UTC
    Server number:  8.0.32.0
    OS Name:        Linux
    OS Version:     4.4.0-116-generic
    Architecture:   amd64
    JVM Version:    1.8.0_161-b12
    JVM Vendor:     Oracle Corporation
    

    Setting CATALINA_BASE explicitly to /var/lib/tomcat8 inside catalina.sh solved the problem in using ./catalina.sh run to start tomcat. In the past, I have alternatively added the soft links to conf, logs and work under the /usr/share/tomcat8 directory so it could find those files and start up properly with the catalina.sh run command.

    BTW, even thought the JRE_HOME is clearly wrong in the version.sh dump above, the service does start correctly (when I append the tail -f command as described earlier). It also starts using catalina.sh run when I manually add the correct CATALINA_BASE variable to catalina.sh. So I spent no time looking into why that listed out incorrectly.

    In the end, I realized three things:

    1. Running multiple services (tomcat / mysql) in a single container is not recommended. Yes, there is supervisor.d, etc. But this is discouraged. There is also baseimage-docker if you are committed to multiple services in one container.
    2. Even running a single service in a container is not recommended but there are documented ways to make it work (which I did for tomcat8 by adding the && tail -f ... to the end of the CMD).
    3. In Ubuntu 16.04 (did not test other distros), to make tomcat8 run as a command (not a service) you need to either: a) grab the tar file for Tomcat 8 and install that, since it puts all of the files under one directory and therefore there is no soft link issue. Or, b) if you insist on using the distro tomcat8 from apt-get, b.1) you need to modify a version of catalina.sh by adding the CATALINA_BASE and copy it to the proper installation directory or b.2) add the soft links.