solr

Deploying Apache Solr 4 on Tomcat 8

For the last week or so, I’ve been struggling with the deployment of Apache Solr on an existing Tomcat 7 installation. That instance of tomcat was running LMF, which proved to be incompatible with Solr. So, I needed a fresh Tomcat installation, and I decided to go with Tomcat 8. So, let’s get going:

Prerequisites and considerations:

I’ve donde this on a Debian-like system, but this should be pretty similar in other platforms. I’m assuming there is already an instance of Apache 2 running, with mod_rewrite, mod_ssl, mod_proxy and mod_ proxy_html, as well as Tomcat 8 up and running, with it’s own user. I’ll assume tomcat lives in /opt/tomcat8

Warning: I’m NOT an expert with Tomcat not solr, so I’m keeping the deployment simple. You may want to toy around with the locations, libraries and so.

Deploying solr on tomcat:

Once you have decided where you want Solr to live, download the tgz from their site, and unpack them. I usually install them on /opt, although a more standard approach will imply using /usr/local, or something similar. So:

root@host:~# cd /opt
root@host:/opt# wget http://apache.rediris.es/lucene/solr/4.10.2/solr-4.10.2.tgz
root@host:/opt# tar xvf solr-4.10.2.tgz
root@host:/opt# mv solr-4.10.2 solr

Keep in mind, Rediris was the best mirror for me, you should use whatever is best for you.

First, you will need to copy some libraries into the tomcat installation:

root@host:/opt# cp solr/example/lib/ext/* /opt/tomcat8/lib

Now, in the solr folder there should be a .war inside the dist folder. That’s the war you need to deploy in tomcat. For convenience, I’ve renamed that war simply to solr.war. Now, create the file conf/Catalina/localhost/solr.xml in your favourite text editor:

<?xml version='1.0' encoding='utf-8'?>
<Context docBase="/opt/solr/dist/solr.war " debug="0" crossContext="true">
    <Environment name="solr/home" type="java.lang.String" value="/opt/solr/example/solr" override="true"/>
</Context>

Make sure the /opt/solr folder is accesible for the tomcat user:

root@host:/opt# chown -R tomcat8:tomcat solr

And restart tomcat.

With this, you should be able to point a browser to host:8080/solr, and access the solr interface. Now, let’s make it a little bit more secure, shall we?

Limiting access to localhost:

To limit the access for localhost, edit the conf/Catalina/localhost/solr.xml and add a RemoteHostValve:

<?xml version='1.0' encoding='utf-8'?>
<Context docBase="/opt/tomcat8/webapps/solr.war " debug="0" crossContext="true">
    <Environment name="solr/home" type="java.lang.String" value="/opt/solr/example/solr" override="true"/>
    <Valve className="org.apache.catalina.valves.RemoteHostValve" allow="0:0:0:0:0:0:0:1|::1|127\.0\.0\.1|localhost|host"/>
</Context>

Once you restart tomcat, you should NOT be able to access the solr interface from any remote host.

Accessing the solr manager through Apache:

We want solr to only be accessible from the host, but we also want to access the manager remotely. So, we will use Apache for that. First, add a Redirect to the standard virtual host, to make sure all connections use HTTPS:

    Redirect /solr https://host/solr

Now, in the ssl virtualhost, we want to setup a proxy using Apache auth. In this example, we are using mod_auth_external, but a basic authentication system should work as well:

    RewriteRule ^/solr$ /solr/ [R]
    ProxyPass /solr/ http://localhost:8080/solr/
    ProxyPassReverse /solr/ http://localhost:8080/solr/
    
    <Location /solr>
        Authtype Basic
        AuthBasicProvider external
        AuthExternal pwauth_auth
        AuthName "Solr server"
        AuthzUnixgroup on
        AuthzUnixgroupAuthoritative off
        Require group admin
    </Location>

(change the 8080 port for whatever port your tomcat uses)
Reload the Apache config, and you should be good to go 🙂

Food for thought

  • Tomcat has it’s own user-control capabilities. Will it be better to use those?
  • For simplicity, we are using the solr “example” installation. A production deployment should be careful to use only what it needs.
  • Since I am running this on the same machine with self-signed certificates, I don’t use https between tomcat and Apache, although it will provably be better from a security point of view.

Fell free to share your opinion about this on the comments!