Skip to content
This repository was archived by the owner on Dec 12, 2023. It is now read-only.

Load Balancing configuration

Sven edited this page Apr 21, 2016 · 26 revisions

Description

The following apache config files describe a possible load balancing setup with mod_proxy. The main problem is the automatic redirect of Wordpress to the original site_url. This behaviour can only be suppressed with disabling this feature (Wordpress Core) or manipulating the HTTP Host Header. The PHP server therefore changes the Host Header from its own name to the site domain expected by Wordpress.

The load balancing functionality is achieved with mod_proxy_balancer and additional PHP servers (server1.integreat-app.de, serverX.integreat-app.de, etc).

Additional performance improvements can be achieved by caching HTML on the proxy server.

Potentially subdomains for every city could also be supported if mod_headers is used to manipulate the GET path for each city subdomain.

Problem: the connection between the proxy and the load balancer is not encrypted. Therefore all resource links are http://. The ssl virtualhost on the load balancer should redirect to a ssl virtualhost on the PHP server as well. Or use mod_substitute to change all URLs from http://cms-test.integreat-app.de to https://cms-test.integreat-app.de

Proxy / Load Balancer

/etc/apache2/sites-enabled/virtualhost.conf

<VirtualHost *:80>
    ServerName cms.integreat-app.de

    #All cities should land here
    ServerAlias *.integreat-app.de
    #the redirect to https://cms.integreat-app.de/cityname/wp-admin/ is managed by a PHP file in the /var/www/redirect/ folder
    DocumentRoot /var/www/redirect

    #mod_rewrite could be used instead of the PHP redirect above
    #RewriteEngine on

    #RewriteCond %{REQUEST_URI} !^\/\.well-known\/
    #RewriteRule (.*) https://%{HTTP_HOST}$1 [L,R=301]

</VirtualHost>

<Virtualhost *:443>
    ServerName cms.integreat-app.de
    DocumentRoot /var/www/redirect/

    #activate SSL, we're using Let's Encrypt
    SSLEngine On
    SSLCertificateFile /etc/letsencrypt/live/cms.integreat-app.de/cert.pem
    SSLCertificateChainFile /etc/letsencrypt/live/cms.integreat-app.de/chain.pem
    SSLCertificateKeyFile /etc/letsencrypt/live/cms.integreat-app.de/privkey.pem

    #Proxy the root location to the PHP backend server. mod_proxy_balancer can be used for balancing
    ProxyPass / http://server1.integreat-app.de/wordpress/
    ProxyPassReverse / http://server1.integreat-app.de/wordpress/

    #Returned headers need to be changed to fit the external URL
    Header edit* Set-Cookie path=/wordpress/ path=/
    Header edit* Set-Cookie server1.integreat-app.de cms.integreat-app.de
    Header edit* Location http:// https://
    Header edit* Location server1.integreat-app.de cms.integreat-app.de
    Header edit* Location /wordpress/ /

    #returned content (e.g. links) needs to be changed to fit the external URL
    #<Location />
    AddOutputFilterByType SUBSTITUTE text/html application/json
    Substitute "s|/wordpress_test/|/|in"
    Substitute "s|http://server1.integreat-app.de/wordpress/|http://cms.integreat-app.de/|in"
    Substitute "s|http://server1.integreat-app.de|https://cms.integreat-app.de|in"
    Substitute "s|server1.integreat-app.de|cms.integreat-app.de|in"
    Substitute "s|http://|https://|in"
    Substitute "s|http:\\/\\/|https:\\/\\/|in"
    Substitute "s|\\/wordpress\\/|\\/|in"
    Substitute "s|/wordpress/|/|in"
    #</Location>
</VirtualHost>

/etc/apache2/sites-enabled/rewrite-rules.conf

<Directory /var/www/redirect>
    #the following section is identical to the .htaccess file of wordpress
    RewriteEngine On
    RewriteBase /wordpress/
    RewriteRule ^index\.php$ - [L]

    # add a trailing slash to /wp-admin
    RewriteRule ^([_0-9a-zA-Z-]+/)?wp-admin$ $1wp-admin/ [R=301,L]

    RewriteCond %{REQUEST_FILENAME} -f [OR]
    RewriteCond %{REQUEST_FILENAME} -d
    RewriteRule ^ - [L]
    RewriteRule ^([_0-9a-zA-Z-]+/)?(wp-(content|admin|includes).*) $2 [L]
    RewriteRule ^([_0-9a-zA-Z-]+/)?(.*\.php)$ $2 [L]
    RewriteRule . index.php [L]

    <Files database.sql>
            Order Allow,Deny
            Deny from all
    </Files>
    <Files wp-config.php>
            Order Allow,Deny
            Deny from all
    </Files>
    <Files config.ini>
            Order Allow,Deny
            Deny from all
    </Files>

</Directory>

PHP Server

/etc/apache/sites-enabled/virtualhost.conf

<VirtualHost *:80>
    ServerAdmin webmaster@localhost
    DocumentRoot /var/www/html/
    ServerName server1.integreat-app.de
    <Directory /var/www/html/wordpress>
            AllowOverride All
            Options -Indexes
    </Directory>
    
    #Changes the Host header field. This prevents wordpress vom redirecting to the site_url
    RequestHeader edit Host server1.integreat-app.de cms.integreat-app.de

    ErrorLog ${APACHE_LOG_DIR}/error.log
    CustomLog ${APACHE_LOG_DIR}/access.log combined
</VirtualHost>

Required Wordpress configuration

The wp_blogs and wp_X_options site_url and site_home entries need to correspond to the proxy server domain. If HTTPS is enabled, some additional configuration is required (to be discussed). Wordpress delivers 403 Forbidden in some cases, which will not be handled by mod_substitute. 403 Forbidden status codes need to be replaced by 200 OK. This should basically be fine as the error messages are "soft errors". The plugin ig-remove-403-forbidden solves this problem.

Clone this wiki locally