Using Apache 2.4 Macros For Website Hosting

Submitted by Tom Thorp on Wednesday, November 21, 2018 - 19:56
Modified on Friday, July 5, 2019 - 21:18
Apache 2.4
When hosting multiple websites on an Apache 2.4 webserver, it can be a tricky proposition. Not only do you have to take into account the type of website, there are access permissions to consider, the directory where it is hosted, as well as what interpreter gets used.
 
What if there was a way to shortcut the process of setting up the website on Apache, as well as making each installation type consistent? Well you can ... with Macros.

 

Apache Macros

Apache Macros allow you to set up scripted templates to use for hosting all of your websites. Like functions, they can be called with parameters allowing you the flexibility to set up various scenarios for each website. 
 
Since version 2.4.6 of Apache, the macro module comes loaded by default on most linux distributions. To check if your installation of Apache has the macro module loaded, run the following command :
 
httpd -M

or 

apachectl -M
If 'macro_module' does not appear in the list of loaded modules, either 
 
# Edit /etc/httpd/conf.modules.d/00-base.conf file and add the following line

LoadModule macro_module modules/mod_macro.so

# or, run the following command 

a2enmod macro

 

Macro Examples

Here are two examples of macros I created for use developing my websites. The first is for Drupal 8.
 
# File conf/httpd.conf

IncludeOptional conf.d/vhost.macro
Use VHost tomthorp tomthorp.intnet /opt/php72


# File conf.d/vhost.macro

<Macro VHost $name $domain $dir>
    <VirtualHost *:80>
        ServerAdmin tom@thorp.com
        ServerName $domain
        ServerAlias www.$domain
        DirectoryIndex index.php

        <FilesMatch \.php$>
            SetHandler "proxy:unix:$dir/var/run/php-fpm.sock|fcgi://localhost"
        </FilesMatch>

        <Proxy fcgi://localhost>
            ProxySet connectiontimeout=5 timeout=240
        </Proxy>

        DocumentRoot /data/www/$name/web
        <Directory /data/www/$name/web>
            Options Indexes FollowSymLinks
            AllowOverride None
            Require all granted
            RewriteEngine on
            RewriteBase /
            RewriteCond %{REQUEST_FILENAME} !-f
            RewriteCond %{REQUEST_FILENAME} !-d
            RewriteCond %{REQUEST_URI} !=/favicon.ico
            RewriteRule ^ index.php [L]
        </Directory>
        
        ErrorLog logs/$domain-error_log
        CustomLog logs/$domain-access_log combined
    </VirtualHost>
</Macro>
The second macro I use is for Wordpress :
 
# File conf/httpd.conf

IncludeOptional conf.d/wpvhost.macro
Use WPVHost wordpress wordpress.intnet /opt/php72


# File conf.d/wpvhost.macro

<Macro WPVHost $name $domain $dir>
    <VirtualHost *:80>
        ServerAdmin tom@thorp.com
        ServerName $domain
        ServerAlias www.$domain

        <FilesMatch \.php$>
            SetHandler "proxy:unix:$dir/var/run/php-fpm.sock|fcgi://localhost"
        </FilesMatch>

        <Proxy fcgi://localhost>
            ProxySet connectiontimeout=5 timeout=240
        </Proxy>

        DirectoryIndex index.php
        DocumentRoot /data/www/$name
        <Directory />
            Options FollowSymLinks 
            AllowOverride None 
        </Directory> 
        <Directory /data/www/$name> 
            Options Indexes FollowSymLinks MultiViews
            AllowOverride All
            Require all granted
            <IfModule mod_rewrite.c>
                RewriteEngine On
                RewriteBase /
                RewriteRule ^index\.php$ - [L]
                RewriteCond %{REQUEST_FILENAME} !-f
                RewriteCond %{REQUEST_FILENAME} !-d
                RewriteRule . /index.php [L]
            </IfModule>
        </Directory>
        ErrorLog logs/$domain-error_log
        CustomLog logs/$domain-access_log combined
    </VirtualHost>
</Macro>
 
In each macro, I have passed three parameters. They are :
  • $name - used for the DocumentRoot of the VirtualHost,
  • $domain - used to identify the internally hosted domain name of the VirtualHost, and
  • $dir - the root directory of the PHP instance serving the VirtualHost
On my server, I built from source several versions of PHP,  in each case configuring PHP-FPM with unix sockets enabled. If you require a tcp host and port to be passed instead of a unix socket, then you would make the required adjustment to the macro in the SetHandler statement.
 
The takeaway from using macros in your Apache configuration, is not only is it simple to set up, your configuration files become less prone to errors. Macros can be used not only in a development environment, but also in a production environment. How you set up your macros in your Apache configuration files, are only limited by your server configuration and your imagination. 
 
 

About the author

Tom Thorp
Tom Thorp is an IT Consultant living in Miami on Queensland's Gold Coast. With over 30+ years working in the IT industry, Tom's experience is a broad canvas. The IT services Tom provides to his clients, includes :
 
Website development and hosting
Database Administration
Server Administration (Windows, Linux, Apple)
PABX Hosting and Administration
Helpdesk Support (end-user & technical).
  If you like any of my content, consider a donation via Crypto by clicking on one of the payment methods :
 
Categories