Install Tomcat 8 behind Nginx with Google PageSpeed in Debian Wheezy

Saturday March 22, 2014 ()

   How to install Tomcat 8 in Debian Wheezy
Here is a guide on how to configure Debian Wheezy with Tomcat 8 behind Nginx with Google PageSpeed. This is based on our recently configured Wheezy of similar setup. Below are the main components of this webserver installation.

  • Nginx with Google PageSpeed and some other Nginx modules
  • Tomcat 8 on Java 7
  • MySQL and phpMyAdmin on php5-fpm.
  • Debian Wheezy Linux server.

Building Nginx with Google PageSpeed

We begun by installing what we need to build Nginx from source.

apt-get update
apt-get install build-essential openssl libssl-dev zlib1g-dev  
    libpcre3 libpcre3-dev php5-fpm unzip openjdk-7-jdk

Accept additional packages that may be suggested by the above command. Next download PageSpeed as shown below.

cd /home/user 
mkdir downloads
cd downloads 
wget https://github.com/pagespeed/ngx_pagespeed/
       archive/release-1.7.30.4-beta.zip
unzip release-1.7.30.4-beta.zip
cd ngx_pagespeed-release-1.7.30.4-beta/
wget https://dl.google.com/dl/page-speed/psol/1.7.30.4.tar.gz
tar xzvf 1.7.30.4.tar.gz  

If for no other reason, it is best to download the latest stable version of Nginx. We download version nginx-1.4.6 as shown below.

cd /home/user/downloads
wget http://nginx.org/download/nginx-1.4.6.tar.gz
tar xvzf nginx-1.4.6.tar.gz
cd nginx-1.4.6/

./configure 
    --prefix=/usr/share/nginx 
    --sbin-path=/usr/sbin/nginx 
    --conf-path=/etc/nginx/nginx.conf 
    --pid-path=/var/run/nginx.pid 
    --lock-path=/var/lock/nginx.lock 
    --error-log-path=/var/log/nginx/error.log 
    --http-log-path=/var/log/access.log 
    --user=www-data 
    --group=www-data 
    --with-ipv6 
    --with-http_ssl_module 
    --with-http_gzip_static_module 
    --with-mail 
    --add-module=/home/user/downloads/ngx_pagespeed-release-1.7.30.4-beta 

There are modules that are compiled by default unless you remove them using --without-{MODULE-NAME} switch. As illustrated above additional modules are included with the --with switch and --add-module for third-party software as with our Google PageSpeed. List of available modules can be found here http://wiki.nginx.org/Modules.

make
su  #if not already
make install

Nginx is now installed. Next is to create a start up script.

cd /etc/init.d/
vi nginx # to create a file called nginx

We used the script that comes with the Debian Nginx package edited to our setup. Here below is that script edit them to match your configuration.

https://kahimyang.com/demo/nginx.txt

chmod +x nginx
update-rc.d nginx defaults

/etc/init.d/nginx start #To start your new webser.
http://yourdomain.com   #Test your new Ngix.

You should see the Nginx diagnostic page that says Nginx is up and running.

In addition to PageSpeed we also used ngx_http_limit_conn_module module, this is part of the standard modules. ngx_http_limit_conn_module helps limit excessive requests to server and defined zones. See line 15 and 16 and also 22 and 23 below . To learn more about this module check out the this http://nginx.org/en/docs/http/ngx_http_limit_conn_module.html documentation.

worker_processes  4; 

events {
    worker_connections  1024;
}

http {
	include       mime.types;
	default_type  application/octet-stream;
	sendfile      on;

	keepalive_timeout  5;
	tcp_nodelay on;

	limit_conn_zone $binary_remote_addr zone=perip:10m;
	limit_conn_zone $server_name zone=perserver:10m;

	server {
		listen       80;
		server_name  kahimyang.info; #replace with yours

		limit_conn perip 10;
		limit_conn perserver 100;

		pagespeed on;

		# Needs to exist and be writable by nginx.
		pagespeed FileCachePath /var/cache/ngx_pagespeed_cache/;

		# Ensure requests for pagespeed optimized 
		# resources go to the pagespeed handler
		# and no extraneous headers get set.
		location ~ "\.pagespeed\.([a-z]\.)?[a-z]{2}\.[^.]{10}\.[^.]+" {
			add_header "" "";
		}
		location ~ "^/ngx_pagespeed_static/" { }
		location ~ "^/ngx_pagespeed_beacon$" { }
		location /ngx_pagespeed_statistics { allow 127.0.0.1; deny all; }
		location /ngx_pagespeed_global_statistics { 
			allow 127.0.0.1; deny all; 
		}
		location /ngx_pagespeed_message { allow 127.0.0.1; deny all; }

		pagespeed RewriteLevel CoreFilters; #default
		pagespeed PreserveUrlRelativity on;
                pagespeed EnableFilters collapse_whitespace,remove_comments;
                #pagespeed EnableFilters resize_mobile_images;

		pagespeed Domain *.twitter.com;
		pagespeed Domain *.fbcdn.net;
		pagespeed Domain *.facebook.net;
        
		location / {
			root /usr/share/nginx/html;
			index index.html index.xhtml index.php;
		}
  
		error_page   500 502 503 504  /50x.html;
		location = /50x.html {
			root   html;
		}

		location ~ \.php$ {
			try_files $uri =404;
			root           /usr/share/nginx/html;
			fastcgi_index  index.php;
			fastcgi_param  SCRIPT_FILENAME $document_root$fastcgi_script_name;
			include        fastcgi_params;
			fastcgi_pass unix:/var/run/php5-fpm.sock;
		}

	}

	# additional server blocks
	include /etc/nginx/sites-enabled/*.conf;

}

Enable PageSpeed with pagespeed on directive (line 25 above) on every server block you want optimized. PageSpeed uses a cache in /var/cache/ngx_pagespeed_cache/ created at start up if it does not exist you only have to make sure it is owned and writable by www-data, the owner of Nginx process. You can manually create this folder if desired.

PageSpeed rewrites and optimizes resources before they are served. We have above the default handler "RewriteLevel CoreFilters" to rewrite and compress resources (css, js, and images) as necessary. This is a set of filters that does the optimization as implied by its name shown in the following.

   add_head
   combine_css
   combine_javascript
   convert_meta_tags
   extend_cache
   fallback_rewrite_css_urls
   flatten_css_imports
   inline_css
   inline_import_to_link
   inline_javascript
   rewrite_css
   rewrite_images
   rewrite_javascript
   rewrite_style_attributes_with_url

Google recommends to use this default, otherwise use RewriteLevel PassThrough and then enable only what you need. See below for example.

pagespeed RewriteLevel PassThrough;
ModPagespeedEnableFilters combine_css,extend_cache,rewrite_images;

Please visit this page https://developers.google.com/speed/pagespeed/module/configuration to learn more.

In addition to optimizing resources of your own domain, PageSpeed promises to also optimize external domains accessed by you application (Lines 47, 48 and 49 of Listing 2).

Our php5-fpm configuration starts at line 61 in listing 2, it is configured to run using Unix Sockets (see line 67 of listing 2 above).

Save configuration as /etc/nginx/nginx and then restart nginx again to test our new PageSpeed and our PHP configuration.

Check your /var/log/nginx/* for errors. At this point, you may want to create a test PHP script, put them in your root, and then access them. Your PageSpeed cache has been created (if you did not created them) and then change ownership (chown -R www-data:www-data /var/cache/ngx_pagespeed_cache) and access permissions (chmod -R 755 www-data:www-data /var/cache/ngx_pagespeed_cache) if necessary.

Tomcat 8

Tomcat 8 supports Servlet 3.1, JSP 2.3, and EL 3.0 and the new WebSocket 1.0 specifications. None of these we need right now, but we figured it best to have it there in case our needs changed very suddenly.

We are installing a single instance Tomcat as a default web server proxied by nginx. As of blog time, Tomcat 8 is available only though Apache Tomcat mirrors.

wget http://www.interior-dsgn.com/apache/tomcat/tomcat-8/
     v8.0.3/bin/apache-tomcat-8.0.3.tar.gz
tar xvfz apache-tomcat-8.0.3.tar.gz

Extract to a desired location. We have extracted our copy to /opt as /opt/apache-tomcat-8.0.3. This path is your CATALINA_HOME, and since we are a single instance installation, this is also your CATALINA_BASE.

ln -s /opt/apache-tomcat-8.0.3 /opt/tomcat

The above is just to make it tidy while still keeping the original version for easy tracking of the versions installed in your system. It creates a symbolic link /opt/tomcat (your new CATALINA_HOME) that points to the original.

Create tomcat user and group to own the tomcat process.

groupadd tomcat
useradd -g tomcat -d /opt/tomcat tomcat
usermod -G www-data tomcat
chown -R tomcat:tomcat /opt/tomcat
chown -R tomcat:tomcat /opt/apache-tomcat-8.0.3 

Create start up script in /etc/init.d

cd /etc/init.d
vi tomcat # to create a file called tomcat

Here again below is the start up script we used edited to our setup. It is a copy of an Ubuntu Tomcat script we found in the internet sometime ago.

https://kahimyang.com/demo/tomcat.txt

chmod +x /etc/init.d/tomcat
update-rc.d tomcat defaults

Change your $CATALINA_HOME/conf/tomcat-users.xml

<tomcat-users>
    <role rolename="manager" />
    <role rolename="manager-gui" />
    <role rolename="admin"/>
    <role rolename="admin-gui"   />
    <user username="{USER}" password="{PASSWORD}"
     roles="admin,admin-gui,manager,manager-gui" />
</tomcat-users>

Edit your $CATALINA_HOME/conf/server.xml Engine block to look like the following. What is shown below only part we needed changed.

<Engine name="Catalina" defaultHost="kahimyang.info">
	<Host name="kahimyang.info"  
            appBase="webapps"
            unpackWARs="true" autoDeploy="true">
     	
		<Context path=""
		    docBase="/opt/tomcat/webapps/kauswagan"
		    debug="0" reloadable="true" /> 
     
		<Valve className="org.apache.catalina.valves.AccessLogValve" 
                    directory="logs"
                    prefix="kahimyang_access_log" suffix=".txt"
                    pattern="%h %l %u %t "%r" %s %b" />

	</Host>
</Engine>

It is worth mentioning that the defaultHost of the Engine and name in the Host should match. The default "HTTP/1.1" connector of Tomcat 8 is non blocking. If you need to change your connector, you have to change the Connector protocol below to either "org.apache.coyote.http11.Http11Protocol" or "org.apache.coyote.http11.Http11AprProtocol". In the later case, Apache Tomcat native libraries must be installed in your system and should match with the Tomcat 8 you have.

<Service name="Catalina">
	<Connector port="8080" 
		protocol="HTT1/1.1"
		connectionTimeout="20000"
		redirectPort="8444" />
</Service>

The path="" in the Context line 6 of Listing 3 tells Tomcat that this is our root.

Tomcat is our main server running behind nginx so we needed to use nginx as a proxy to our Tomcat running on port 8080. From our /etc/nginx/nginx.conf, we added a location inside our main server block.

location / {
	index  index.xhtml; 
	root /opt/tomcat/webapps;
	proxy_set_header X-Forwarded-Host $host;
	proxy_set_header X-Forwarded-Server $host;
	proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
	proxy_pass https://kahimyang.com:8080; 
}

This should replace the location / {...} we have earlier from line 53 to 56 in Listing 2. This will forward root access to your Tomat application on port 8080.

Save, restart nginx and test Tomcat like below.

http://yourdomain.com

MySQL and phpMyAdmin

Installing MySQL in Debian Whezzy with Nginx is straightforward but installing phpMyAdmin will also install Apache. So we decided download phpMyAdmin and them install manually.

First install MySQL and its dependencies.

apt-get install mysql-client mysql-server php5-mysql mcrypt php5-mcrypt

Accept additional package that may be suggested by apt-get and respond to prompts of MySQL installer. Also create additional user other that root and grant that user the necessary privileges. You use this new user to access your MySQL installation through phpMyAdmin.

Download phpMyAdmin

cd /usr/share/nginx/html
wget http://sourceforge.net/projects/phpmyadmin/files/
           phpMyAdmin/4.1.9/phpMyAdmin-4.1.9-english.tar.gz
tar xvfz phpMyAdmin-4.1.9-english.tar.gz

ln -s /usr/share/nginx/html/phpMyAdmin-4.1.9-english 
          /usr/share/nginx/html/phpmyadmin

The phpMyAdmin home then becomes /usr/share/nginx/phpmyadmin.

Edit nginx configuration to add the phpAdmin location like below. This should be inserted in your main server block in Listing 2.

location /phpmyadmin {
	try_files $uri =404;
	index index.php index.html index.htm;
	root           /usr/share/nginx/html;
	fastcgi_index  index.php;
	fastcgi_param  SCRIPT_FILENAME  $document_root$fastcgi_script_name;
	include        fastcgi_params;
	fastcgi_pass unix:/var/run/php5-fpm.sock;

location ~* ^/phpmyadmin/(.+\.(jpg|jpeg|gif|css|png|js|ico|html|xml|txt))$ {
		root /usr/share/nginx/html;
	}
}

Restart nginx and access your phpMyAdmin.

http://yourdomain.com/phpmyadmin

You should see the user and password prompt.

Finally

Don't forget to rotate your logs. Scripts to rotate Nginx access logs has to be created yourself. Tomcat logs has also to be rotated. Here is a blog on how to rotate logs. Other software you may consider installed are Monit (or its equivalent), Shorewall or similar, and an anti-virus program.

That's it. Good luck.


5,795

Comments (Install Tomcat 8 behind Nginx with Google PageSpeed in Debian Wheezy)