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.

Plesk rebuild Apache configuration files

Sometimes you need to rebuild all your httpd.include files, it can be done with websrvmng command:

/usr/local/psa/admin/bin/websrvmng -av

Redirect to www.domain.com with Nginx

Depending on your requirements you’ll need to redirect your users from domain.com to www.domain.com with a permanent redirect in order to improve your site SEO ranking. We already know how to do it with apache and mod_rewrite, but how do you make it in nginx ? It’s not too hard.

Apache configuration:

#.htaccess
RewriteEngine On
RewriteCond %{HTTP_HOST} !^www\.domain\.com
RewriteRule (.*) http://www.domain.com$1 [R=301,L]

Nginx configuration:

# /etc/nginx/nginx.conf
if ($http_host !~ "^www\.domain\.com$") {
    rewrite  ^(.*)    http://www.domain.com$1 permanent;
}