[tomcat] How to config Tomcat to serve images from an external folder outside webapps?

How can i use Tomcat to serve image files from a public folder outside webapps? I dont want to use a 2nd Apache fileserver on a different port since the image files are part of the same app. And i dont want to create a symlink to the public folder inside webapps since my app is deployed as a war file....Is there a simpler solution similar to using default servlet for static content inside webapps, for static content outside outside webapps

This question is related to tomcat

The answer is


You can deploy an images folder as a separate webapp and define the location of that folder to be anywhere in the file system.

Create a Context element in an XML file in the directory $CATALINA_HOME/conf/[enginename]/[hostname]/ where enginename might be 'Catalina' and hostname might be 'localhost'.

Name the file based on the path URL you want the images to be viewed from, so if your webapp has path 'blog', you might name the XML file blog#images.xml and so that your images would be visible at example.com/blog/images/

The content of the XML file should be <Context docBase="/filesystem/path/to/images"/>

Be careful not to undeploy this webapp, as that could delete all your images!


This is very simple and straight forward to server the static content from outside webapps folder in tomcat.

Simply edit the server.xml under $CATALINA_HOME/config/server.xml as below and restart the tomcat.

<Host name="localhost"  appBase="webapps"
            unpackWARs="true" autoDeploy="true">

        **<Context docBase="C:\Ankur\testFiles"  path="/companyLogo" />**

       <Valve className="org.apache.catalina.valves.AccessLogValve" directory="logs"
               prefix="localhost_access_log" suffix=".txt"
               pattern="%h %l %u %t &quot;%r&quot; %s %b" />

</Host>

Add the context element inside the host element with two attribute docBase and path.

1) docBase: represents the hard drive directory 2) path: represents the uri on which you want to serve the static content.

For example:If you have 7.png inside the C:\Ankur\testFiles directory then you can access the 7.png file like below:

http://localhost:8081/companyLogo/7.png

For more details, check the blog


Instead of configuring Tomcat to redirect requests, use Apache as a frontend with the Apache Tomcat connector so that Apache is only serving static content, while asking tomcat for dynamic content.

Using the JKmount directive (or others) you could specify exactly which requests are sent to Tomcat.

Requests for static content, such as images, would be served directly by Apache, using a standard virtual host configuration, while other requests, defined in the JKMount directive will be sent to Tomcat workers.

I think this implementation would give you the most flexibility and control on the overall application.


This is the way I did it and it worked fine for me. (done on Tomcat 7.x)

Add a <context> to the tomcat/conf/server.xml file.

Windows example:

<Context docBase="c:\Documents and Settings\The User\images" path="/project/images" />

Linux example:

<Context docBase="/var/project/images" path="/project/images" />

Like this (in context):

<Server port="8025" shutdown="SHUTDOWN">
 ...
  <Service name="Catalina">
    ...
    <Engine defaultHost="localhost" name="Catalina">
     ...
     <Host appBase="webapps"
      autoDeploy="false" name="localhost" unpackWARs="true"
      xmlNamespaceAware="false" xmlValidation="false">
      ...
      <!--MAGIC LINE GOES HERE-->
       <Context  docBase="/var/project/images" path="/project/images" />

      </Host>
    </Engine>
  </Service>
</Server>

In this way, you should be able to find the files (e.g. /var/project/images/NameOfImage.jpg) under:

http://localhost:8080/project/images/NameOfImage.jpg 

Instead of configuring Tomcat to redirect requests, use Apache as a frontend with the Apache Tomcat connector so that Apache is only serving static content, while asking tomcat for dynamic content.

Using the JKmount directive (or others) you could specify exactly which requests are sent to Tomcat.

Requests for static content, such as images, would be served directly by Apache, using a standard virtual host configuration, while other requests, defined in the JKMount directive will be sent to Tomcat workers.

I think this implementation would give you the most flexibility and control on the overall application.


Instead of configuring Tomcat to redirect requests, use Apache as a frontend with the Apache Tomcat connector so that Apache is only serving static content, while asking tomcat for dynamic content.

Using the JKmount directive (or others) you could specify exactly which requests are sent to Tomcat.

Requests for static content, such as images, would be served directly by Apache, using a standard virtual host configuration, while other requests, defined in the JKMount directive will be sent to Tomcat workers.

I think this implementation would give you the most flexibility and control on the overall application.


After none of solutions based on defining XMLs worked for me, I found this answer very helpful. Took about a minute, and a small code change: I modified this line

this.basePath = getServletContext().getRealPath(getInitParameter("basePath"));

into

this.basePath = getInitParameter("basePath");


You can deploy an images folder as a separate webapp and define the location of that folder to be anywhere in the file system.

Create a Context element in an XML file in the directory $CATALINA_HOME/conf/[enginename]/[hostname]/ where enginename might be 'Catalina' and hostname might be 'localhost'.

Name the file based on the path URL you want the images to be viewed from, so if your webapp has path 'blog', you might name the XML file blog#images.xml and so that your images would be visible at example.com/blog/images/

The content of the XML file should be <Context docBase="/filesystem/path/to/images"/>

Be careful not to undeploy this webapp, as that could delete all your images!


This is the way I did it and it worked fine for me. (done on Tomcat 7.x)

Add a <context> to the tomcat/conf/server.xml file.

Windows example:

<Context docBase="c:\Documents and Settings\The User\images" path="/project/images" />

Linux example:

<Context docBase="/var/project/images" path="/project/images" />

Like this (in context):

<Server port="8025" shutdown="SHUTDOWN">
 ...
  <Service name="Catalina">
    ...
    <Engine defaultHost="localhost" name="Catalina">
     ...
     <Host appBase="webapps"
      autoDeploy="false" name="localhost" unpackWARs="true"
      xmlNamespaceAware="false" xmlValidation="false">
      ...
      <!--MAGIC LINE GOES HERE-->
       <Context  docBase="/var/project/images" path="/project/images" />

      </Host>
    </Engine>
  </Service>
</Server>

In this way, you should be able to find the files (e.g. /var/project/images/NameOfImage.jpg) under:

http://localhost:8080/project/images/NameOfImage.jpg 

After none of solutions based on defining XMLs worked for me, I found this answer very helpful. Took about a minute, and a small code change: I modified this line

this.basePath = getServletContext().getRealPath(getInitParameter("basePath"));

into

this.basePath = getInitParameter("basePath");


Instead of configuring Tomcat to redirect requests, use Apache as a frontend with the Apache Tomcat connector so that Apache is only serving static content, while asking tomcat for dynamic content.

Using the JKmount directive (or others) you could specify exactly which requests are sent to Tomcat.

Requests for static content, such as images, would be served directly by Apache, using a standard virtual host configuration, while other requests, defined in the JKMount directive will be sent to Tomcat workers.

I think this implementation would give you the most flexibility and control on the overall application.


Many years later, we can do the following with Spring Web MVC, inside our webapp-servlet.xml file:

<mvc:resources mapping="/static/**" location="/static/" />

In Tomcat 7, you can use "aliases" property. From the docs:

This attribute provides a list of external locations from which to load resources for this context. The list of aliases should be of the form "/aliasPath1=docBase1,/aliasPath2=docBase2" where aliasPathN must include a leading '/' and docBaseN must be an absolute path to either a .war file or a directory. A resource will be searched for in the first docBaseN for which aliasPathN is a leading path segment of the resource. If there is no such alias, then the resource will be searched in the usual way. These external locations will not be emptied if the context is un-deployed.

Many years later, we can do the following with Spring Web MVC, inside our webapp-servlet.xml file:

<mvc:resources mapping="/static/**" location="/static/" />

In Tomcat 7, you can use "aliases" property. From the docs:

This attribute provides a list of external locations from which to load resources for this context. The list of aliases should be of the form "/aliasPath1=docBase1,/aliasPath2=docBase2" where aliasPathN must include a leading '/' and docBaseN must be an absolute path to either a .war file or a directory. A resource will be searched for in the first docBaseN for which aliasPathN is a leading path segment of the resource. If there is no such alias, then the resource will be searched in the usual way. These external locations will not be emptied if the context is un-deployed.

This is very simple and straight forward to server the static content from outside webapps folder in tomcat.

Simply edit the server.xml under $CATALINA_HOME/config/server.xml as below and restart the tomcat.

<Host name="localhost"  appBase="webapps"
            unpackWARs="true" autoDeploy="true">

        **<Context docBase="C:\Ankur\testFiles"  path="/companyLogo" />**

       <Valve className="org.apache.catalina.valves.AccessLogValve" directory="logs"
               prefix="localhost_access_log" suffix=".txt"
               pattern="%h %l %u %t &quot;%r&quot; %s %b" />

</Host>

Add the context element inside the host element with two attribute docBase and path.

1) docBase: represents the hard drive directory 2) path: represents the uri on which you want to serve the static content.

For example:If you have 7.png inside the C:\Ankur\testFiles directory then you can access the 7.png file like below:

http://localhost:8081/companyLogo/7.png

For more details, check the blog