Loading...
Real Time Concepts

ProxyPass Instead of Varnish

Why use ProxyPass instead of Varnish?

Who wants to run a separate daemon and worry about it crashing or have to change port configs? Not
Me. So lets get started not doing that.

Step One: Configure Apache Modules (Ubuntu Only)

This strategy requires that mod_proxy and mod_proxy_http are enabled. These seem to be enabled by default on Red Hat Apache installs. For Ubuntu, these commands will do the trick:

  • a2enmod proxy_http
  • service apache2 restart

Step Two: Configure Environment

I find it easiest if all the servers have their /etc/hosts set up, so we know web1
is the master. For example, if the master server’s IP is 192.168.5.1 you could run this on all the slave hosts:

echo 192.168.5.1 web1 >> /etc/hosts

Step Three: Configure your VirtualHost

In your VirtualHost configuration on all slave servers, but the following:

# Turn on all the things
RewriteEngine On
ProxyPreserveHost On
SSLProxyEngine on

# /wp-admin/ goes to web1
ProxyPass /wp-admin/ https://web1/wp-admin/
ProxyPassReverse /wp-admin/ https://web1/wp-admin/

# All post requsets go to web1
RewriteCond %{REQUEST_METHOD} =POST
RewriteRule . https://web1%{REQUEST_URI} [P]

# If a file is a static file, and can’t be found, try and get it from web1
RewriteCond %{REQUEST_URI} ^/.*(\.)(png|jpg|jpeg|css|js)$
RewriteCond %{REQUEST_URI} !-f
RewriteRule . https://web1%{REQUEST_URI Sessions} [P]

sessions

WordPress does not actually use PHP sessions. It uses a cookie to determine if you are authenticated but does not store session data for your user. In all cases where we have an lsyncd master server you will want to configure some kind of shared session storage. This is because when the request is proxied back to the master that server will have no idea of the session and the user will appear to be logged out and their cookie if any could be unset.

Recipes

We have a working recipe for WordPress sites but we should think about testing other popular CMS we see: Joomla, Drupal, etc.
Custom code will always be a one off, we need to be able to match requests that are writing/deleting files to the filesystem and write proper proxy statements to pass them to the master.

Considerations:

The example above works for WordPress and also passes all POST requests back up to the master. If a site is very post heavy this could put a strain on the master server, or not. This recipe doesn’t take into account modules that may allow user generated content to be uploaded.

We know that for default WordPress installation ProxyPassing the /wp-admin/ url to the master will handle everything for you. For most setups proxying POST method requests to the master will also be sufficient. However, if the client uses a GET request to modify content in any way (such as deleting a file; we noticed this with WordPress) then that request must also be passed back to the master, or the file will not get deleted on the master server. This is a problem with Varnish as well.

I suggest using lsyncd to sync Apache configuration files between all servers. In the case of an Ubuntu server you will want to exclude the /etc/apache2/envvars file, because the master must not have the DSLAVE option set to the apache2 binary.

Tips & Warnings

  • You may see the below error when running a configuration test before reloading apache, this is likely due to mod_proxy not being enabled.

# apache2ctl -t
AH00526: Syntax error on line 9 of /etc/apache2/sites-enabled
/example.com.conf:
Invalid command ‘ProxyPreserveHost’, perhaps misspelled or defined
by a module not included in the server configuration
Action ‘-t’ failed.

To check this, comment out the changes in the vhost file and run the below:

### mod_proxy not enabled
# apache2ctl -M | grep proxy

# a2enmod proxy
### mod_proxy now enabled
# apache2ctl -M | grep proxy
proxy_module (shared)

Apache2.4 complaining that MASTER_SERVER isn’t definded:

[Thu Mar 24 10:55:49.877064 2016] [core:warn] [pid 28074] AH00111:
Config variable ${MASTER_SERVER} is not defined
[Thu Mar 24 10:55:49.877203 2016] [core:warn] [pid 28074] AH00111:
Config variable ${MASTER_SERVER} is not defined

Add the below line to /etc/httpd/conf/httpd.conf Before the line that Includes conf.d/*.conf or
vhost.d/*.conf

Define MASTER_SERVER 10.0.0.0

Leave a Reply

Your email address will not be published. Required fields are marked *