Welcome,
In this walkthrough we will look at installing the binary distribution of Tomcat 8 on Ubuntu Server 14.04 LTS. Please note that we will not use Tomcat-native package here. Apache 2.4 will be used as a front optionally handling static content and ssl-termination while dynamic content will be served by the Tomcat-server through the Apache JServ Protocol (AJP 1.3) with apache module mod_jk.
First we need to install a Java Runtime that the Tomcat-server will run in. I chose the server-jre8-version for obvious reason. The Server JRE is a runtime environment specifically targeted for deploying Java in server environments and it is available for 64-bit Linux, Solaris and Windows platforms. The Server JRE includes tools for JVM monitoring and tools commonly required for server applications, but does not include browser integration (the Java plug-in).
The Server JRE can be downloaded from this location: http://www.oracle.com/technetwork/java/javase/downloads/server-jre8-downloads-2133154.html
At the time of my download, this was the latest version available:
server-jre-8u45-linux-x64.tar.gz
Download it to /usr/src/download or any other location you prefer and unpack.
root@ubuntu01:/usr/src/download# tar xvzf server-jre-8u45-linux-x64.tar.gz
That will create the folder /usr/src/download/jdk1.8.0_45
Change the owner recursively on that folder, I’m using root as user and group here.
root@ubuntu01:/usr/src/download# chown -R root:root jdk1.8.0_45/
Move the folder to your desired location, I chose /opt here since that folder is typically for third-party add-on software.
root@ubuntu01:/usr/src/download# mv jdk1.8.0_45/ /opt
To make it obvious that this is the Server JRE I created a symlink pointing to that folder.
root@ubuntu01:/opt# ln -s jdk1.8.0_45/ server_jre root@ubuntu01:/opt# ls -al drwxr-xr-x 8 root root 4096 Apr 10 19:22 jdk1.8.0_45 lrwxrwxrwx 1 root root 12 Jul 1 11:18 server_jre -> jdk1.8.0_45/
Just to verify this is the correct java version
root@ubuntu01:/opt/server_jre/bin# ./java -version java version "1.8.0_45" Java(TM) SE Runtime Environment (build 1.8.0_45-b14) Java HotSpot(TM) 64-Bit Server VM (build 25.45-b02, mixed mode)
That’s all for the Java installation, now let’s download and install Tomcat.
Tomcat installation:
Download Tomcat binary distribution:
root@ubuntu01:/usr/src/download# wget http://apache.mirrors.spacedump.net/tomcat/tomcat-8/v8.0.23/bin/apache-tomcat-8.0.23.tar.gz
Unpack
root@ubuntu01:/usr/src/download# tar xvzf apache-tomcat-8.0.23.tar.gz
Move to /opt
root@ubuntu01:/usr/src/download# mv apache-tomcat-8.0.23 /opt/
create symlink in /opt folder
root@ubuntu01:/usr/src/download# cd /opt/ root@ubuntu01:/opt# ln -s apache-tomcat-8.0.23/ tomcat
For security purposes, Tomcat should be run as an unprivileged user. We will create a new user (tomcat) and group (tomcat) that will run the Tomcat-service.
root@ubuntu01:/opt# groupadd tomcat
Then create a new tomcat user. We’ll make this user a member of the tomcat group, with a home directory of /opt/tomcat, and with a shell of /bin/false
root@ubuntu01:/opt# useradd -s /bin/false -g tomcat -d /opt/tomcat tomcat
Change to the new user and group recursively on the tomcat folder structure
root@ubuntu01:/opt# chown -R tomcat:tomcat apache-tomcat-8.0.23
Now it should look like this when listing the /opt folder:
root@ubuntu01:/opt# ls -al drwxr-xr-x 9 tomcat tomcat apache-tomcat-8.0.23 drwxr-xr-x 8 root root jdk1.8.0_45 lrwxrwxrwx 1 root root server_jre -> jdk1.8.0_45/ lrwxrwxrwx 1 root root tomcat -> apache-tomcat-8.0.23/
Now, comment out the port 8080 connector in server.xml…(we will only enable AJP on port 8009)
root@ubuntu01:/opt# cd tomcat/conf/ root@ubuntu01:/opt/tomcat/conf# vi server.xml
<!-- <Connector port="8080" protocol="HTTP/1.1" connectionTimeout="20000" redirectPort="8443" /> -->
Make sure the ajp-connector is not disabled…
<Connector port="8009" protocol="AJP/1.3" redirectPort="8443" />
Configure Tomcat Web Management Interface. Put this in your tomcat-users.xml in between the <tomcat-users> tags, choose your username and password.
root@ubuntu01:/opt/tomcat/conf# vi tomcat-users.xml
<role rolename="manager-gui"/> <user username="admin" password="password" roles="manager-gui"/>
Because we want to be able to run Tomcat as a service, we will set up an Upstart script. Create and install a Tomcat Upstart script:
root@ubuntu01:/opt/tomcat/conf# vi /etc/init/tomcat.conf
Put this content in the new file:
description "Tomcat Server" start on runlevel [2345] stop on runlevel [!2345] respawn respawn limit 10 5 setuid tomcat setgid tomcat env JAVA_HOME=/opt/server_jre env CATALINA_HOME=/opt/tomcat # Modify these options as needed env JAVA_OPTS="-Djava.awt.headless=true -Djava.security.egd=file:/dev/./urandom" env CATALINA_OPTS="-Xms512M -Xmx1024M -server -XX:+UseParallelGC" exec $CATALINA_HOME/bin/catalina.sh run # cleanup temp directory after stop post-stop script rm -rf $CATALINA_HOME/temp/* end script
Tomcat can now be started/stopped by the service command. It will also startup automatically on boot.
root@ubuntu01:/opt/tomcat/conf# service tomcat start tomcat start/running, process 5666
The log file is located at /var/log/upstart/tomcat.log
root@ubuntu01:/var/log/upstart# tail tomcat.log
Looking at the log file after startup…
…we can see the following message in the log output:
org.apache.catalina.core.AprLifecycleListener.lifecycleEvent The APR based Apache Tomcat Native library which allows optimal performance in production environments was not found on the java.library.path: /usr/java/packages/lib/amd64:/usr/lib64:/lib64:/lib:/usr/lib
Ignore this message. The library referred to is bundled into an OS specific libtcnative.so (or dll for windows) loaded via JNI. It allows Tomcat to use OS functionalities not provided in the Java Runtime (such as sendfile, epoll, OpenSSL, OS level functionality (random number generation, system status, etc), and native process handling (shared memory, NT pipes and Unix sockets). Tomcat will run just fine without it, these features allows making Tomcat a general purpose webserver. We will however only use Tomcat as a backend-server working together with the Apache-webserver, hence we ignore this message.
Installing and configuring mod_jk
root@ubuntu01:/var/log/upstart# apt-get install libapache2-mod-jk Preparing to unpack .../libapache2-mod-jk_1%3a1.2.37-3_amd64.deb ... Unpacking libapache2-mod-jk (1:1.2.37-3) ... Setting up libapache2-mod-jk (1:1.2.37-3) ... apache2_invoke: Enable module jk * Restarting web server apache2
Now with the following command we can see that the module jk_module has indeed been loaded.
root@ubuntu01:/var/log/upstart# apache2ctl -M Loaded Modules: core_module (static) so_module (static) watchdog_module (static) http_module (static) log_config_module (static) logio_module (static) version_module (static) unixd_module (static) access_compat_module (shared) alias_module (shared) auth_basic_module (shared) authn_core_module (shared) authn_file_module (shared) authz_core_module (shared) authz_host_module (shared) authz_user_module (shared) autoindex_module (shared) deflate_module (shared) dir_module (shared) env_module (shared) filter_module (shared) jk_module (shared) mime_module (shared) mpm_prefork_module (shared) negotiation_module (shared) php5_module (shared) rewrite_module (shared) setenvif_module (shared) status_module (shared)
In the jk.conf file we can see where the workers.properties file is located:
root@ubuntu01:/var/log/upstart# cd /etc/apache2/mods-available/ root@ubuntu01:/etc/apache2/mods-available# more jk.conf # Configuration Example for mod_jk # used in combination with Apache 2.2.x <IfModule jk_module> # We need a workers file exactly once # and in the global server JkWorkersFile /etc/libapache2-mod-jk/workers.properties # Our JK error log # You can (and should) use rotatelogs here JkLogFile /var/log/apache2/mod_jk.log # Our JK log level (trace,debug,info,warn,error) JkLogLevel info # Our JK shared memory file JkShmFile /var/log/apache2/jk-runtime-status
…we can see that the workers.properties is located under /etc/libapache2-mod-jk
Edit the workers.properties file, put in your path to your tomcat_home and java_home:
# # workers.tomcat_home should point to the location where you # installed tomcat. This is where you have your conf, webapps and lib # directories. # workers.tomcat_home=/opt/tomcat # # workers.java_home should point to your Java installation. Normally # you should have a bin and lib directories beneath it. # workers.java_home=/opt/server_jre
Make sure the other settings are correctly put in here, should look similar to this:
worker.list=ajp13_worker worker.ajp13_worker.port=8009 worker.ajp13_worker.host=localhost worker.ajp13_worker.type=ajp13 worker.ajp13_worker.lbfactor=1 worker.loadbalancer.type=lb worker.loadbalancer.balance_workers=ajp13_worker
Finally to configure the URLs that Apache should pass through the Tomcat, edit your VirtualHost directive:
root@ubuntu01:/etc/libapache2-mod-jk# cd /etc/apache2/sites-available/ root@ubuntu01:/etc/apache2/sites-available# vi vhosts-default.conf
<VirtualHost *:80> ServerName www.example.com DocumentRoot /var/www/example ErrorLog ${APACHE_LOG_DIR}/error.log CustomLog ${APACHE_LOG_DIR}/access.log combined <Directory /var/www/example> Options Indexes FollowSymLinks AllowOverride None Require all granted </Directory> JkMount /manager/* ajp13_worker JkMount /manager ajp13_worker JkMount /examples/* ajp13_worker JkMount /examples ajp13_worker </VirtualHost>
As you can see we are using the www.example.com domain here just for instructional purpose. Since I’m not the owner of that domain and cannot make any DNS-configuration, such as adding an A-record, for that domain I will put in an entry into my client computer host file just to get this example working. The document root I set to /var/www/example so let’s create that folder first. That location is where any static content optionally will be placed if any, it depends on how you do your jkmount-mappings above. As we can see anything with /manager or /examples will be mapped to Tomcat and the rest will be searched for, by Apache, in the /var/www/example folder.
root@ubuntu01:/var/www# mkdir example
In the client machine I now temporarily set a record to map the url www.example.com to my servers ip-address. I’m using a windows client machine here and editing the hosts-file in notepad as Administrator (right-click-> Run as Administrator). Windows will first look in the host-file and then resolve names with DNS which is exactly the order of precedence we want here in order for this example to work.
C:\Windows\System32\drivers\etc\hosts
85.225.140.7 www.example.com
After a reload of Apache…
root@ubuntu01:/etc/apache2/sites-available# service apache2 reload
We can now point the browser on the windows client machine to try out if everything works:
The Tomcat examples webapp is indeed working. Now trying /manager…
After login with your admin/password this is what welcomes you…
That is all for now. Everything works as expected. Please consider if you really want the /manager mappings to be enabled all of the time. For security reasons I prefer to enable that mapping only when I have to do some deployment. Keep in mind that any password sent over http is sent “in the clear” for any eavesdropper to pick up, you better use https in that case. I will later blog about setting up SSL using SNI with Apache. Edit! Now available here: http://www.creang.com/howtoforge/setting_up_sni_with_apache_2_4/
THANK, YOU!!!
Thanks for the instructions.
On my Ubuntu 14.04 machine, the default sites file is named 000-default.conf.
Thanks. Greate post.
Reading the docs in https://tomcat.apache.org/tomcat-3.3-doc/Tomcat-Workers-HowTo.html I found that the property “balance_workers” shuld be “balanced_workers”.
worker.loadbalancer.balanced_workers=ajp13_worker
Ups. I found that balanced_workers was deprecated and replaced by balance_workers form mod_jk versions 1.2.7 and up.
https://tomcat.apache.org/connectors-doc/reference/workers.html