Easy Rails virtual hosts with mod_macro

Keeping a separate file for each virtual host in /etc/httpd/vhosts.d it’s clean and cool, but when you have many virtual hosts with same settings it’s a pain to keep them updated. We need a template system for Apache configurations and mod_macro module it’s a handy tool for this job.

Download module version suited for your Apache from:
http://www.cri.ensmp.fr/~coelho/mod_macro/

Ensure that you have httpd-devel package installed then untar archive and compile mod_macro module with apxs:

[root@silver tmp]# wget http://www.cri.ensmp.fr/~coelho/mod_macro/mod_macro-1.1.10.tar.bz2
 
[...]
 
[root@silver tmp]# tar xvfjp mod_macro-1.1.10.tar.bz2 
 
[...]
 
[root@silver tmp]# cd mod_macro-1.1.10
[root@silver mod_macro-1.1.10]# apxs -cia mod_macro.c 
/usr/lib64/apr-1/build/libtool --silent --mode=compile gcc -prefer-pic -O2 -g -pipe -Wall -Wp,-D_FORTIFY_SOURCE=2 -fexceptions -fstack-protector --param=ssp-buffer-size=4 -m64 -mtune=generic -fno-strict-aliasing  -DLINUX=2 -D_REENTRANT -D_GNU_SOURCE -pthread -I/usr/include/httpd  -I/usr/include/apr-1   -I/usr/include/apr-1   -c -o mod_macro.lo mod_macro.c && touch mod_macro.slo
mod_macro.c: In function 'looks_like_an_argument':
mod_macro.c:316: warning: cast from pointer to integer of different size
mod_macro.c: In function 'say_it':
mod_macro.c:929: warning: cast from pointer to integer of different size
/usr/lib64/apr-1/build/libtool --silent --mode=link gcc -o mod_macro.la  -rpath /usr/lib64/httpd/modules -module -avoid-version    mod_macro.lo
/usr/lib64/httpd/build/instdso.sh SH_LIBTOOL='/usr/lib64/apr-1/build/libtool' mod_macro.la /usr/lib64/httpd/modules
/usr/lib64/apr-1/build/libtool --mode=install cp mod_macro.la /usr/lib64/httpd/modules/
cp .libs/mod_macro.so /usr/lib64/httpd/modules/mod_macro.so
cp .libs/mod_macro.lai /usr/lib64/httpd/modules/mod_macro.la
cp .libs/mod_macro.a /usr/lib64/httpd/modules/mod_macro.a
chmod 644 /usr/lib64/httpd/modules/mod_macro.a
ranlib /usr/lib64/httpd/modules/mod_macro.a
PATH="$PATH:/sbin" ldconfig -n /usr/lib64/httpd/modules
----------------------------------------------------------------------
Libraries have been installed in:
   /usr/lib64/httpd/modules
 
If you ever happen to want to link against installed libraries
in a given directory, LIBDIR, you must either use libtool, and
specify the full pathname of the library, or use the `-LLIBDIR'
flag during linking and do at least one of the following:
   - add LIBDIR to the `LD_LIBRARY_PATH' environment variable
     during execution
   - add LIBDIR to the `LD_RUN_PATH' environment variable
     during linking
   - use the `-Wl,--rpath -Wl,LIBDIR' linker flag
   - have your system administrator add LIBDIR to `/etc/ld.so.conf'
 
See any operating system documentation about shared libraries for
more information, such as the ld(1) and ld.so(8) manual pages.
----------------------------------------------------------------------
chmod 755 /usr/lib64/httpd/modules/mod_macro.so
[activating module `macro' in /etc/httpd/conf/httpd.conf]

Create a file that will keep your macros in Apache’s conf.d directory (example: _mod_macro.conf), conf.d files are executed after modules are loaded:

# /etc/httpd/conf.d/_mod_macro.conf
 
# RailsHost macro
<Macro RailsHost $host $dir>
  <VirtualHost *:80>
    ServerName www.$host
    ServerAlias $host
    DocumentRoot $dir/current/public
 
    CustomLog "logs/$host_access.log" combined
    ErrorLog "logs/$host_error.log"
 
    # Passenger settings
    RailsBaseURI /
    RailsMaxPoolSize 1
    RailsPoolIdleTime 3600
    RailsEnv production
 
    # Redirect example.com -> www.example.com
    RewriteEngine On
    RewriteCond %{HTTP_HOST} !^www.$host
    RewriteRule ^/(.*) http://www.$host/$1 [R=301,L]
 
    # Check for maintenance file and redirect all requests
    RewriteCond %{DOCUMENT_ROOT}/system/maintenance.html -f
    RewriteCond %{SCRIPT_FILENAME} !maintenance.html
    RewriteCond %{SCRIPT_FILENAME} !^/images
    RewriteCond %{SCRIPT_FILENAME} !^/stylesheets
    RewriteCond %{SCRIPT_FILENAME} !^/javascripts
    RewriteRule ^.*$ /system/maintenance.html [L]
 
    ErrorDocument 404 $dir/current/public/404.html
    ErrorDocument 422 $dir/current/public/422.html
    ErrorDocument 500 $dir/current/public/500.html
 
    Use ModDeflate
    Use ModExpires
 
    <Directory $dir/current/public>
      Options FollowSymLinks
      AllowOverride None
      Order allow,deny
      Allow from all
    </Directory>
  </VirtualHost>
</Macro>
 
# ModDeflate macro
<Macro ModDeflate>
  <IfModule mod_deflate.c>
    AddOutputFilterByType DEFLATE text/plain
    AddOutputFilterByType DEFLATE text/html
    AddOutputFilterByType DEFLATE text/xml
    AddOutputFilterByType DEFLATE text/css
    AddOutputFilterByType DEFLATE application/xml
    AddOutputFilterByType DEFLATE application/xhtml+xml
    AddOutputFilterByType DEFLATE application/rss+xml
    AddOutputFilterByType DEFLATE application/javascript
    AddOutputFilterByType DEFLATE application/x-javascript
 
    BrowserMatch ^Mozilla/4 gzip-only-text/html
    BrowserMatch ^Mozilla/4\.0[678] no-gzip
    BrowserMatch \bMSIE !no-gzip !gzip-only-text/html
  </IfModule>
</Macro>
 
# ModExpires macro
<Macro ModExpires>
  <IfModule mod_expires.c>
    ExpiresActive On
    <LocationMatch "^/(images|javascripts|stylesheets)">
      ExpiresDefault "access plus 1 year"
    </LocationMatch>
  </IfModule>
</Macro>

Append RailsHost macro calls to your httpd.conf to define your virtual hosts :

# /etc/httpd/conf/httpd.conf
 
[...]
 
Use RailsHost vhost1.com /data/virtualhosts/vhost1.com
Use RailsHost vhost2.com /data/virtualhosts/vhost2.com

Now, your Apache configuration looks much better and when it comes make changes to your configurations you’ll need to change just one macro.

1 comment so far ↓

#1 MArc on 11.18.09 at 8:11 pm

Very nice, thank you

Leave a Comment