Have you ever wondered why there's a folder /var/lib/tomcats/ adjacent to /var/lib/tomcat ? Just empty, nothing inside it?  Well the extra s is super helpful when you want to run multiple instances of tomcats, presumably with different configurations.

Say you want to have two instances of tomcats:

  • One tomcat instance named "tom" running on port 8000 with an environment variable called ANIMAL=cat
  • Another instance named "jerry" running on port 8001 with the same environment variable set to "mouse" i.e. ANIMAL=mouse

Now, we'll be creating directories where configurations and WAR files live for these instances:

mkdir -p /var/lib/tomcats/{tom,jerry}/{conf,work,temp,webapps,logs}
This is a cool syntax you can use to create multiple nested directories at once.

Then, make a copy of default configurations:

cp /etc/tomcat/* /var/lib/tomcats/tom/conf/
cp /etc/tomcat/* /var/lib/tomcats/jerry/conf/

To change listening port for instances, change server.xml inside each instance's conf dir.

Now, onto setting environment variables and other variables you could change in /etc/tomcat/tomcat.conf previously, you can set these on per-instance basis by creating a copy of /etc/sysconfig/tomcat and overriding settings:

cp /etc/sysconfig/tomcat /etc/sysconfig/[email protected]
cp /etc/sysconfig/tomcat /etc/sysconfig/[email protected]

echo "ANIMAL=cat" >> /etc/sysconfig/[email protected]
echo "ANIMAL=mouse" >> /etc/sysconfig/[email protected]

Finally, start these services with:

systemctl start [email protected]
systemctl start [email protected]

And, you are done!

You might be wondering how systemctl finds these tomcats even though we created no systemd configuration for these particular instances. The answer lies in the file /usr/lib/systemd/system/[email protected] . Systemd unit files with @ in their names are used to identify so-called templated unit files.  Anyhing passed after @ is used as variables for substitution in that unit file. So, [email protected] would actually call this unit file with an argument "tom". You can confirm this by looking at the file:

[Unit]
Description=Apache Tomcat Web Application Container
After=syslog.target network.target

[Service]
Type=simple
EnvironmentFile=/etc/tomcat/tomcat.conf
Environment="NAME=%I"
EnvironmentFile=-/etc/sysconfig/[email protected]%I
ExecStart=/usr/libexec/tomcat/server start
ExecStop=/usr/libexec/tomcat/server stop
SuccessExitStatus=143
User=tomcat
Group=tomcat

[Install]
WantedBy=multi-user.target

Here, %I would be "tom" and "jerry" respectively; finally something on systemd to be excited about.