Setting up the Apache web server with Play

Apache is the most widely used web server. If you are already using it, you can set up Apache httpd as a proxy for your Play application, instead of exposing it to the Internet directly.

This recipe shows you how to configure SSL and non-SSL Play applications together with the Apache httpd. This chapter features a couple of recipes on how to use a web server as a proxy for Play. In any configuration example one assumption is made: You want to use SSL, but you do not want to use the built-in SSL support of the Play framework, because you are using a proxy in front of your Play application. The forwarding from the external SSL port is done to the internal Play application. However, the internal application does not use SSL. This prevents doing encryption twice or redirecting SSL directly to the Play application. However, you still have to make sure the Play application handles the request as if it came via HTTPS.

The source code of the example application is available at examples/chapter7/ssl/example-app as well as for examples/chapter7/ssl/example-app-2 for the second application instance, which is needed for clustering. The configuration files for the web server are put at examples/chapter7/apache.

Getting ready

You should have an Apache 2 web server up and running. Furthermore, you should have the following modules enabled: mod_ssl, mod_headers, mod_proxy, mod_proxy_http, mod_proxy_balancer. The last one is only needed in case you want to do load balancing. When using a Debian derived distribution like Ubuntu, you can use the a2enmod command, for example a2enmod ssl to enable the SSL module.

How to do it...

The only thing you need to change on your Play application.conf, is the configuration about proxies, which redirect to Play. The IP referenced here is the one from the host Apache runs on:

XForwardedSupport=192.168.0.1

This is a simple Apache configuration for redirecting from external port 80 to internal IP and port 9000 of your Play application.

Note

Be aware that the configuration snippets are highly specific and might not work with your Apache configuration. If you have a web server with several virtual domains you have to specify a name in the <VirtualHost> directive. The snippets here have been tried without any other virtual hosts running on the apache instance. Please refer to the Apache documentation when having a more complex setup.

<VirtualHost *:80>
      ProxyPreserveHost on
      ProxyPass / http://192.168.0.2:9000/
      ProxyPassReverse / http://192.168.0.2:9000/
</VirtualHost>

Now a configuration for redirecting an external SSL connection to internal HTTP, but still making sure it is handled as SSL by the Play application:

<VirtualHost *:443>
        SSLEngine on
        SSLCertificateFile    /etc/ssl/host.crt
        SSLCertificateKeyFile /etc/ssl/host.key

        ProxyPreserveHost on
        ProxyPass / http://192.168.0.2:9000/
        ProxyPassReverse / http://192.168.0.2:9000/
        RequestHeader set "X-Forwarded-SSL" "on"
        RequestHeader set "X-Forwarded-Proto" "https"
</VirtualHost>

The main difference here is the enabling of SSL and adding a special header, which will tell Play to mark this request as secure.

The next possible step is to cluster your application by running it on several nodes:

<Proxy balancer://playcluster>
        BalancerMember http://192.168.0.2:9000
        BalancerMember http://192.168.0.3:9000
</Proxy>

<VirtualHost *:80>
       ProxyPreserveHost on
       ProxyPass / balancer://playcluster/
       ProxyPassReverse / balancer://playcluster/
</VirtualHost>

How it works...

The Play configuration itself is merely a security feature. The support for proxy forwarding should be done explicitly. Instead of a single IP address you can also supply a comma separated list of IP addresses.

Depending on your setup, for example either by using localhost or only IP addresses, you also might have to use the ProxyPassReverseCookieDomain to make sure session cookies are set and handled correctly. Furthermore, it is not the best idea to use a wild card virtual host definition, but rather use name or IP-based virtual hosts. This has just been done out of convenience in this case. Also you should make sure to really use the RequestHeader instead of the Header directive to add the needed headers, as this directive ensures the headers are set before the request is forwarded to Play.

If you are seeking an answer about why the SSL code works and is then set up correctly, the answer is simple. This is a framework convention. You can read about it directly in the source at play.mvc.Http.Request.parseXForwarded().

Regarding load balancing, you need to replace the real hostname in the proxy-specific directive with the balancer configuration. As the Play framework has been designed as a real share nothing system, there is no need to add complex configurations like sticky session IDs, where load balancing is done by keeping the session ID of a node mapped to the application server instance, which always means to keep state on the redirect host. The configuration for SSL has to be done accordingly.

Also be aware that the trailing slash in the ProxyPass and ProxyPassReverse directives is absolutely essential, regardless of whether you are doing balanced or single forwarding, because you have to match to a URL in this case.

There's more...

As Apache is widely used, there is not much point in showing off other features that aren't needed. However, you can even do transparent upgrades of your applications with zero downtime!

Transparent upgrade of your application

As this feature of upgrading your application without any downtime is already written in the documentation, it does not make any sense to talk about it in this book, so just check out http://www.playframework.org/documentation/1.1.1/production#Apacheasafrontproxytoallowtransparentupgradeofyourapplication.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.15.186.79