title: Tomcat behind Apache using ajp for Spring Boot application
body: <p>I've been trying to configure Apache web server with a Spring Boot app that uses embedded Tomcat. Before Spring Boot I used to create an ajp.conf file like:</p>
  
  <pre><code>&lt;VirtualHost *:80&gt;
     ServerName localhost
     &lt;Proxy *&gt;
        AddDefaultCharset Off
        Order deny,allow
        Allow from all
     &lt;/Proxy&gt;
  
     ProxyPass /app ajp://localhost:8009/app
     ProxyPassReverse /app ajp://localhost:8009/app
  
   &lt;/VirtualHost&gt;
  </code></pre>
  
  <p>And include in the httpd.conf file like</p>
  
  <pre><code>Include /opt/lampp/apache2/conf/ajp.conf
  </code></pre>
  
  <p>And in the Tomcat's server.xml file, I used to configure it to listen to port 8009</p>
  
  <pre><code>&lt;Connector port="8009" protocol="AJP/1.3" redirectPort="8443" connectionTimeout="5000"
  </code></pre>
  
  <p>This setup works. But, now with Spring Boot I am trying to achieve something similar with an embedded tomcat. I read <a href="http://docs.spring.io/spring-boot/docs/current-SNAPSHOT/reference/htmlsingle/#howto-use-tomcat-behind-a-proxy-server" rel="noreferrer">Spring Boot Documentation</a> here and added the following propertied on my application.yml file:</p>
  
  <pre><code>server:
      port: 8080
      tomcat:
          remote_ip_header: x-forwarded-for
          protocol_header: x-forwarded-proto
  </code></pre>
  
  <p>My ajp.conf file looks like so:</p>
  
  <pre><code>&lt;VirtualHost *:80&gt;
     ServerName localhost
     &lt;Proxy *&gt;
        AddDefaultCharset Off
        Order deny,allow
        Allow from all
     &lt;/Proxy&gt;
  
     ProxyPass /app ajp://localhost:8009/
     ProxyPassReverse /app ajp://localhost:8009/
  
   &lt;/VirtualHost&gt;
  </code></pre>
  
  <p>I have my spring boot tomcat configuration class as</p>
  
  <pre><code>@Configuration
  public class TomcatConfiguration {
  
  private final Logger log = LoggerFactory.getLogger(TomcatConfiguration.class);
  
  @Bean
  public EmbeddedServletContainerFactory servletContainer() {
      TomcatEmbeddedServletContainerFactory tomcat = new TomcatEmbeddedServletContainerFactory();
      tomcat.addAdditionalTomcatConnectors(createConnector());
      tomcat.addContextValves(createRemoteIpValves());
      return tomcat;
  }
  
  private RemoteIpValve createRemoteIpValves(){
      RemoteIpValve remoteIpValve = new RemoteIpValve();
      remoteIpValve.setRemoteIpHeader("x-forwarded-for");
      remoteIpValve.setProtocolHeader("x-forwarded-protocol");
      return remoteIpValve;
  }
  
  private Connector createConnector() {
      Connector connector = new Connector("org.apache.coyote.http11.Http11NioProtocol");
      Http11NioProtocol protocol = (Http11NioProtocol) connector.getProtocolHandler();
      connector.setScheme("ajp");
      connector.setProtocol("AJP/1.3");
      connector.setRedirectPort(8443);
      //connector.setSecure(true);
      connector.setPort(8009);
      return connector;
  }
  </code></pre>
  
  <p>On my apache error logs I see:</p>
  
  <pre><code>AH01080: ajp_msg_check_header() got bad signature 4854
  [proxy_ajp:error] [pid 24073] AH01031: ajp_ilink_receive() received bad header
  [proxy_ajp:error] ajp_read_header: ajp_ilink_receive failed
  [proxy_ajp:error] (120007)APR does not understand this error code: [client xx.xx.xx.xx:60916] AH00878: read response failed from (null) (*)
  </code></pre>
  
  <p>Not sure what's going on here. I searched a lot online, but could not find a good documentation on how to serve tomcat behind apache with spring boot apps. Eventually, I would like to load balance multiple tomcat instances too.</p>