Installing mod_jk on apache httpd in CentOS 6.x/7.x

CentOS again. Today I'm going to show you how to install and configure mod_jk in apache httpd using a server with CentOS. Currently this tutorial was tested on Centos 6.x and 7.x so you should run out of troubles if you stick with one of those versions.

Introduction

So, what's mod_jk? mod_jk is an apache httpd module used to make apache tomcat applications interact with a httpd server. In simple words, mod_jk allows us to connect an instance of tomcat with the apache httpd web server. This is useful for example if you have your httpd serving different kind of webapps (php, RoR, etc) and you want to publish a java app running on a tomcat instance. In this case, httpd run in port 80 and tomcat (usually) in port 8080, so we need to connect somehow the tomcat instance with httpd so our users can interact with our java app directly from port 80. In this case, the httpd server is giving us access to for example an internal network where your tomcat instances live. See the next diagram for a visual explanation:

tomcat-httpd-connector

Why not use mod_proxy?

This is indeed a good question. From a stackoverflow question/answer:

mod_proxy:

  • Pros:
    • No need for a separate module compilation and maintenance. mod_proxy, mod_proxy_http, mod_proxy_ajp and mod_proxy_balancer comes as part of standar Apache 2.2+ distribution.
    • Ability to use http/https or AJP protocols, even with the same balancer.
  • Cons:
    • mod_proxy_ajp does not support larke 8k+ packet sizes.
    • Basic load balancer.
    • Does not support Domain model clustering.

mod_jk:

  • Pros:
    • Advanced load balancer.
    • Advanced node failure detection.
    • Support for large AJP packet sizes.
  • Cons:
    • Need to build and mantain a separate module.

So, the discussion is there, no final answer. A good article covering this topic is: "Deciding between mod_jk, mod_proxy_http and mod_proxy_ajp" from Tomcat Experts.

Installation

The installation process for mod_jk is really simple but we're going to need to compile the module first. Before doing any compile work, ensure you have both httpd and tomcat installed. Now:

Now, go to the official mod_jk website and download the latest version: http://tomcat.apache.org/download-connectors.cgi (1.2.41 at the published date of the post):

In the native folder (check the last step in the code above) we're going to configure-make-make install the connector:

UPDATE (May 16, 2016): The user Matthew Herzog in the comments pointed me that apxs has moved to /usr/bin/apxs as opposed to /usr/sbin/apxs. In my system I still have apxs on /usr/sbin but if you run into troubles doing the previous steps maybe this can help.

2nd UPDATE (May 16, 2016): The user Akash Hikadi reported on the comments that to make the previous command to work he had to add the flag enable-api-compatibility. If you get the next error when doing the previous steps "No targets specified and no makefile found" or "No rule to make target install" try running:

If all goes well you're going to have the mod_jk.so installed on your /etc/httpd/modules folder.

Configuration

First, lets enable the AJP connection on your tomcat server, in your server.xml configuration file:

Add under the <Service name="Catalina"> tag:

And modify the Engine tag so its looks like:

Observation 1: for each tomcat instance linked to your httpd server, you need to define a different jvmRoute parameter. For example, for a second instance you could use:

Now, lets go with the httpd configuration. First, create a mod_jk.conf file in your conf.d folder:

And populate the file with the following:

Before continuing, create the folder to store the shared memory of the module:

Now, create the workers.properties file: (look at the JkWorkersFile property on mod_jk.conf file):

With the next content:

For every app server from tomcat to httpd you're going to have a specific worker. Don't forget to define the worker first in the worker.list property. For example, lets assume we're going to add another app from tomcat:

Well, everything looks good now. The final step is to configure the VirtualHost for every app on httpd:

It's a good practice to maintain your VirtualHosts in separated files. Now, in your recently created app1.conf file:

We are connecting httpd with tomcat using the JkMount directive in the VirtualHost configuration. If for example you'are adding a VirtualHost for your second app use the app2Worker configured previously and so on for other apps.

Final steps and conclusion

If you followed all the previous steps, you should be able to interact with your tomcat app directly from http://app1.myhost.com which is handled by httpd. Beautiful!

In this tutorial, we learned how to use mod_jk to connect different tomcat instances with the httpd web server. The procedure is straighforward but involves some compile tasks and a few configurations on each server. If you have any dobts don't hesitate to initiate a converstion in the comments sections.

Share:
Diego Acuña

Diego Acuña

I'm a Software Engineering and Web Developer from Chile. My main interests are web technologies, software development methodologies and data mining (mainly on financial area). If you want to get in touch with me, use the contact page from the top menu.

  • Pingback: Food Concerns – Random thoughts on software development and computer science()

  • Ricardo Bejarano Espinoza

    Hi, this tutorial can work with glassfish?

  • Akash Hikadi

    When I execute "make libtool --finsih /usr/lib64/httpd/modules" I am getting the error unrecognsed option --finish. Any help or suggestions? I am doing it in centos.

    • Akash Hikadi

      I got it. Add an option --enable-api-compatibility at the end to command "./configure...." which should look like as follows. "./configure --with-apxs=/usr/sbin/apxs --enable-api-compatibility"

  • Matthew Herzog

    apxs has moved to /usr/bin as opposed to /usr/sbin.

    Thanks a lot for this page. Nice work.

  • gabo

    hi
    thanks 4 the tutorial

    i found a litle correction with the s:
    JkWorkersFile /etc/httpd/conf/workers.properties

    vim /etc/httpd/conf/worker.properties

    saludos!

    • Diego Acuña

      Thanks for the correction!

  • mmetli

    hi

    thanks for the tutorial

    I have followed every step in this tutorials but apache is not connecting to tomcat. in the mod_jk.log is have [Tue May 31 12:40:28 2016] [18286:140627988510784] [info] init_jk::mod_jk.c (3591): mod_jk/1.2.41 initialized

    my workers.properties is

    worker.list=node1

    worker.stat1.type=status

    worker.node1.port=8009
    worker.node1.host=localhost
    worker.node1.type=ajp13

    and mod_jk.conf is

    #Load mod_jk module
    #Specify the filename of the mod_jk lib
    LoadModule jk_module "/etc/httpd/modules/mod_jk.so"

    #Where to find workers.properties
    JkWorkersFile /etc/httpd/conf/workers.properties

    # Where to put jk shared memory
    JkShmFile /var/run/httpd/mod_jk.shm

    # Where to put jk logs
    JkLogFile /var/log/httpd/mod_jk.log

    # Set the jk log level [debug/error/info]
    JkLogLevel info

    #JkOptions +ForwardKeySize +ForwardURICompat -ForwardDirectories +ForwardLocalAddress

    # Select the timestamp log format
    JkLogStampFormat "[%a %b %d %H:%M:%S %Y] "

    #JkRequestLogFormat set the request format
    JkRequestLogFormat "%w %V %T"

    # Select the timestamp log format
    #JkLogStampFormat "[%a %b %d %H:%M:%S %Y] "

    #JkRequestLogFormat "%w %V %T"
    #JkEnvVar SSL_CLIENT_V_START worker1

    my app1.conf is

    ServerName localhost
    LogFormat "%h %l %u %t "%r" %>s %b "%{Referer}i" "%{User-agent}i"" combined
    CustomLog /var/log/httpd/app1_access.log combined
    ErrorLog /var/log/httpd/app1_error.log

    JkMount /examples/* node1
    JkMount /examples node1
    JkMount /* node1
    JkMount / node1

    Please help out. Thank you

  • Bruno Silveira

    Hi....congrat's!!

    It is important to remember of start httpd service.

  • Patrik Perháč

    should I also set a variables for tomcat and java in /.bashrc ....?

    • Diego Acuña

      in both cases I think it shouldn't be necessary

  • If you're hung up using the Amazon Linux AMI due to not finding axps in Ec2 after getting these errors:
    --> Processing Conflict: httpd24-2.4.23-1.66.amzn1.x86_6
    --> Processing Conflict: httpd24-tools-2.4.23-1.66.amzn1
    I did this:
    $sudo yum install httpd24-devel.x86_64
    then edit from /sbin to /bin:
    $sudo ./configure --with-apxs=/usr/bin/apxs
    and continue with the ./configure...

  • disqus_LApHPk2P6u

    conf.d loads modules in alphabetical order. This means app1 loads before mod_jk and this fails
    JkMount /* app1Worker

    Also, It should be

    Best thing to do would be to load the mod_jk module before the optional ones in conf.d. Basically just add Include /etc/httpd/conf.d/mod_jk.conf in httpd conf.

    Also what does /var/run/mod_jk do? Why create it?
    It looks like its configured to run from:
    # Where to put jk shared memory
    JkShmFile /var/run/httpd/mod_jk.shm

  • Fazil Parappurath A

    Thank you!

  • Mohammad Amir

    I am facing this error

    Forbidden

    You don't have permission to access / on this server.

    • Diego Acuña

      Sounds like a problem in the configuration of your apache httpd. Check your config and the permission on the served folders.

  • Cristian Loki

    wget http://www-us.apache.org/dist/tomcat/tomcat-connectors/jk/tomcat-connectors-1.2.42-src.tar.gz

    apxs has moved to /usr/bin as opposed to /usr/sbin.

    remember of start httpd service.

    Thanks ! This help me a lot.