Centos8 + Apache + Tomcat + LetsEncrypt Setup


A popular setup for Tomcat is to run it as a backend behind Apache. This lets you use Apache for some websites and URLs and Tomcat for others (while keeping the same IP address and port).

Another common requirement is to have a valid SSL certificate.

This HOWTO describes that setup. The HOWTO is for Centos8, but it would not be too different for other distros.

Run a clean install choosing Centos8 at https://rimuhosting.com/cp/vps/disk/install.jsp

In /etc/httpd/conf.modules.d/00-proxy.conf enable:

LoadModule proxy_module modules/mod_proxy.so
LoadModule proxy_ajp_module modules/mod_proxy_ajp.so

Run the following:

domain=example.com
systemctl enable mariadb
systemctl start mariadb
yum -y install apr apr-util
yum -y install certbot
yum -y install python3-certbot-apache
wget -O installjava.sh http://proj.ri.mu/installjava.sh
wget -O installtomcat.sh http://proj.ri.mu/installtomcat.sh
bash installjava.sh --jre 15
bash installtomcat.sh --version 9
systemctl stop httpd
# get a certificate first, so those files exist, so apache and tomcat do not complain they are missing
certbot --standalone certonly -d $domain -d www.$domain
# disable the default ssl host e.g. with <IfModule undefined>
vi /etc/httpd/conf.d/ssl.conf
# permit tomcat user to read cert files
chmod o+xr /etc/letsencrypt/live
chmod o+rx /etc/letsencrypt/archive/
chmod o+r /etc/letsencrypt/archive/$domain/privkey*
# make tomcat/conf/server.xml changes per below
# renew the certificate and setup renewal hooks (needs to restart/reload tomcat/apache)
certbot --apache certonly -d $domain -d www.$domain --force-renewal --post-hook "systemctl restart tomcat; systemctl reload httpd;"

[root@example logs]# mysql
Your MariaDB connection id is 9
Server version: 10.3.17-MariaDB MariaDB Server

[root@example logs]# /usr/local/tomcat/bin/version.sh
Using CATALINA_BASE: /usr/local/tomcat
Server version: Apache Tomcat/8.5.60
Server built: Nov 12 2020 17:31:55 UTC
Server number: 8.5.60.0
JVM Version: 15.0.1+9-18

[root@example logs]# cat /etc/redhat-release
CentOS Linux release 8.2.2004 (Core)

[root@example logs]# apachectl -Sv
Server version: Apache/2.4.37 (centos)
Server built: Sep 15 2020 15:41:16

Sample Apache VirtualHost config:

<VirtualHost *:80>
    ServerName example.com
    ServerAlias www.example.com example.com
    ServerAdmin webmaster@example.com
    DocumentRoot /var/www/example.com/public_html

Redirect / https://www.example.com/webapp

ErrorLog /var/log/httpd/example.com-error.log
CustomLog /var/log/httpd/example.com-access.log combined

</VirtualHost>

<IfModule mod_ssl.c>
<VirtualHost *:443>
    ServerName example.com
    ServerAlias www.example.com example.com
    ServerAdmin webmaster@example.com
    DocumentRoot /var/www/example.com/public_html

RedirectMatch ^/$ https://www.example.com/webapp
RewriteCond %{HTTPS} off
RewriteRule ^ https://%{HTTP_HOST}%{REQUEST_URI}

        ProxyPass /.well-known !

        ProxyPass /webapp ajp://127.0.0.1:8009/webapp retry=0 timeout=9000
        ProxyPassReverse /webapp ajp://127.0.0.1:8009/webapp


 ErrorLog /var/log/httpd/example.com-error.log
 CustomLog /var/log/httpd/example.com-access.log combined


Include /etc/letsencrypt/options-ssl-apache.conf
SSLCertificateFile /etc/letsencrypt/live/example.com/cert.pem
SSLCertificateKeyFile /etc/letsencrypt/live/example.com/privkey.pem
SSLCertificateChainFile /etc/letsencrypt/live/example.com/fullchain.pem

</VirtualHost>
</IfModule>

And tomcat/conf/server.xml changes like:

     <Connector URIEncoding="UTF-8" port="8080" protocol="HTTP/1.1"
+		address="127.0.0.1"
                connectionTimeout="20000"
                redirectPort="8443" />
     <!-- A "Connector" using the shared thread pool-->
@@ -99,26 +100,26 @@
          Either JSSE or OpenSSL style configuration may be used. OpenSSL style
          configuration is used below.
     -->
-    <!--
     <Connector URIEncoding="UTF-8" port="8443" protocol="org.apache.coyote.http11.Http11AprProtocol"
+		adddress="127.0.0.1"
                maxThreads="150" SSLEnabled="true" >
         <UpgradeProtocol className="org.apache.coyote.http2.Http2Protocol" />
         <SSLHostConfig>
-            <Certificate certificateKeyFile="conf/localhost-rsa-key.pem"
-                         certificateFile="conf/localhost-rsa-cert.pem"
-                         certificateChainFile="conf/localhost-rsa-chain.pem"
-                         type="RSA" />
+            <Certificate certificateKeyFile="/etc/letsencrypt/live/example.com/privkey.pem"
+                         certificateFile="/etc/letsencrypt/live/example.com/fullchain.pem"
+                         certificateChainFile="/etc/letsencrypt/live/example.com/fullchain.pem"
+                          type="RSA" />
+
         </SSLHostConfig>
     </Connector>
-    -->
 
     <!-- Define an AJP 1.3 Connector on port 8009 -->
-    <!--
     <Connector protocol="AJP/1.3"
-               address="::1"
+               address="127.0.0.1"
+		secretRequired="false"
+
                port="8009"
                redirectPort="8443" />
-    -->